diff --git a/ReleaseNotes.md b/ReleaseNotes.md index c9a48cd57bff2039da821ee5c64fe11f3bca137e..de748a59cc0c46c2d8795d9c099300b4a17db73d 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -3,8 +3,25 @@ ## Summary ### Features - - cta/CTA#1016 New options for filtering deleted files using `cta-admin rtf ls` command. - - cta/CTA#983 Add cta-release package for public binary rpm distribution. + +# v4.2-1 + +## Summary + +### Features +- cta/CTA#1001 Maximum file size is now defined by VO instead of globally. +- cta/CTA#1019 New command `cta-readtp` allows reading files from tape and verifying their checksum + +# v4.1-1 + +## Summary + +### Features +- cta/CTA#1016 New options for filtering deleted files using `cta-admin rtf ls` command. +- cta/CTA#983 Add cta-release package for public binary rpm distribution. +- cta/CTA#980 Add external encryption script option +- cta/CTA#976 Define a new table in the DB schema to contain the drive status. +- cta/CTA#834 New command "recycletf restore" allows undeleting a copy of a file from tape deleted using tapefile rm - [frontend] New command "tapefile rm" allows deleting a copy of a file from tape diff --git a/catalogue/4.2/mysql_catalogue_schema.sql b/catalogue/4.2/mysql_catalogue_schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..e88ac3e28dc852cb88be5973bd65270f75c1308c --- /dev/null +++ b/catalogue/4.2/mysql_catalogue_schema.sql @@ -0,0 +1,422 @@ +CREATE TABLE ARCHIVE_FILE_ID( + ID BIGINT UNSIGNED, + CONSTRAINT ARCHIVE_FILE_ID_PK PRIMARY KEY(ID) +); +INSERT INTO ARCHIVE_FILE_ID(ID) VALUES(1); +CREATE TABLE LOGICAL_LIBRARY_ID( + ID BIGINT UNSIGNED, + CONSTRAINT LOGICAL_LIBRARY_ID_PK PRIMARY KEY(ID) +); +INSERT INTO LOGICAL_LIBRARY_ID(ID) VALUES(1); +CREATE TABLE MEDIA_TYPE_ID( + ID BIGINT UNSIGNED, + CONSTRAINT MEDIA_TYPE_ID_PK PRIMARY KEY(ID) +); +INSERT INTO MEDIA_TYPE_ID(ID) VALUES(1); +CREATE TABLE STORAGE_CLASS_ID( + ID BIGINT UNSIGNED, + CONSTRAINT STORAGE_CLASS_ID_PK PRIMARY KEY(ID) +); +INSERT INTO STORAGE_CLASS_ID(ID) VALUES(1); +CREATE TABLE TAPE_POOL_ID( + ID BIGINT UNSIGNED, + CONSTRAINT TAPE_POOL_ID_PK PRIMARY KEY(ID) +); +INSERT INTO TAPE_POOL_ID(ID) VALUES(1); +CREATE TABLE VIRTUAL_ORGANIZATION_ID( + ID BIGINT UNSIGNED, + CONSTRAINT VIRTUAL_ORGANIZATION_ID_PK PRIMARY KEY(ID) +); +INSERT INTO VIRTUAL_ORGANIZATION_ID(ID) VALUES(1); +CREATE TABLE FILE_RECYCLE_LOG_ID( + ID BIGINT UNSIGNED, + CONSTRAINT FILE_RECYCLE_LOG_ID PRIMARY KEY(ID) +); +INSERT INTO FILE_RECYCLE_LOG_ID(ID) VALUES (1); +CREATE TABLE CTA_CATALOGUE( + SCHEMA_VERSION_MAJOR BIGINT UNSIGNED CONSTRAINT CTA_CATALOGUE_SVM1_NN NOT NULL, + SCHEMA_VERSION_MINOR BIGINT UNSIGNED CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL, + NEXT_SCHEMA_VERSION_MAJOR BIGINT UNSIGNED, + NEXT_SCHEMA_VERSION_MINOR BIGINT UNSIGNED, + STATUS VARCHAR(100), + IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL, + CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1')) +); +CREATE TABLE ADMIN_USER( + ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT ADMIN_USER_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT ADMIN_USER_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT ADMIN_USER_LUT_NN NOT NULL, + CONSTRAINT ADMIN_USER_PK PRIMARY KEY(ADMIN_USER_NAME) +); +CREATE TABLE DISK_SYSTEM( + DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_DSNM_NN NOT NULL, + FILE_REGEXP VARCHAR(100) CONSTRAINT DISK_SYSTEM_FR_NN NOT NULL, + FREE_SPACE_QUERY_URL VARCHAR(1000) CONSTRAINT DISK_SYSTEM_FSQU_NN NOT NULL, + REFRESH_INTERVAL BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_RI_NN NOT NULL, + TARGETED_FREE_SPACE BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_TFS_NN NOT NULL, + SLEEP_TIME BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_ST_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT DISK_SYSTEM_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_LUT_NN NOT NULL, + CONSTRAINT NAME_PK PRIMARY KEY(DISK_SYSTEM_NAME) +); +CREATE TABLE VIRTUAL_ORGANIZATION( + VIRTUAL_ORGANIZATION_ID BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_VOI_NN NOT NULL, + VIRTUAL_ORGANIZATION_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL, + READ_MAX_DRIVES BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL, + WRITE_MAX_DRIVES BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL, + MAX_FILE_SIZE BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_LUT_NN NOT NULL, + CONSTRAINT VIRTUAL_ORGANIZATION_PK PRIMARY KEY(VIRTUAL_ORGANIZATION_ID), + CONSTRAINT VIRTUAL_ORGANIZATION_VON_UN UNIQUE(VIRTUAL_ORGANIZATION_NAME) +); +CREATE TABLE STORAGE_CLASS( + STORAGE_CLASS_ID BIGINT UNSIGNED CONSTRAINT STORAGE_CLASS_SCI_NN NOT NULL, + STORAGE_CLASS_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_SCN_NN NOT NULL, + NB_COPIES TINYINT UNSIGNED CONSTRAINT STORAGE_CLASS_NC_NN NOT NULL, + VIRTUAL_ORGANIZATION_ID BIGINT UNSIGNED CONSTRAINT STORAGE_CLASS_VOI_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT STORAGE_CLASS_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT STORAGE_CLASS_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT STORAGE_CLASS_LUT_NN NOT NULL, + CONSTRAINT STORAGE_CLASS_PK PRIMARY KEY(STORAGE_CLASS_ID), + CONSTRAINT STORAGE_CLASS_SCN_UN UNIQUE(STORAGE_CLASS_NAME), + CONSTRAINT STORAGE_CLASS_VOI_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID) +); +CREATE TABLE TAPE_POOL( + TAPE_POOL_ID BIGINT UNSIGNED CONSTRAINT TAPE_POOL_TPI_NN NOT NULL, + TAPE_POOL_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_TPN_NN NOT NULL, + VIRTUAL_ORGANIZATION_ID BIGINT UNSIGNED CONSTRAINT TAPE_POOL_VOI_NN NOT NULL, + NB_PARTIAL_TAPES BIGINT UNSIGNED CONSTRAINT TAPE_POOL_NPT_NN NOT NULL, + IS_ENCRYPTED CHAR(1) CONSTRAINT TAPE_POOL_IE_NN NOT NULL, + SUPPLY VARCHAR(100), + USER_COMMENT VARCHAR(1000) CONSTRAINT TAPE_POOL_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT TAPE_POOL_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT TAPE_POOL_LUT_NN NOT NULL, + CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_ID), + CONSTRAINT TAPE_POOL_TPN_UN UNIQUE(TAPE_POOL_NAME), + CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1')), + CONSTRAINT TAPE_POOL_VO_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID) +); +CREATE TABLE ARCHIVE_ROUTE( + STORAGE_CLASS_ID BIGINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_SCI_NN NOT NULL, + COPY_NB TINYINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_CN_NN NOT NULL, + TAPE_POOL_ID BIGINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_TPI_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT ARCHIVE_ROUTE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_LUT_NN NOT NULL, + CONSTRAINT ARCHIVE_ROUTE_PK PRIMARY KEY(STORAGE_CLASS_ID, COPY_NB), + CONSTRAINT ARCHIVE_ROUTE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID), + CONSTRAINT ARCHIVE_ROUTE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), + CONSTRAINT ARCHIVE_ROUTE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0), + CONSTRAINT ARCHIVE_ROUTE_SCI_TPI_UN UNIQUE(STORAGE_CLASS_ID, TAPE_POOL_ID) +); +CREATE TABLE MEDIA_TYPE( + MEDIA_TYPE_ID BIGINT UNSIGNED CONSTRAINT MEDIA_TYPE_MTI_NN NOT NULL, + MEDIA_TYPE_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_MTN_NN NOT NULL, + CARTRIDGE VARCHAR(100) CONSTRAINT MEDIA_TYPE_C_NN NOT NULL, + CAPACITY_IN_BYTES BIGINT UNSIGNED CONSTRAINT MEDIA_TYPE_CIB_NN NOT NULL, + PRIMARY_DENSITY_CODE TINYINT UNSIGNED, + SECONDARY_DENSITY_CODE TINYINT UNSIGNED, + NB_WRAPS INT UNSIGNED, + MIN_LPOS BIGINT UNSIGNED, + MAX_LPOS BIGINT UNSIGNED, + USER_COMMENT VARCHAR(1000) CONSTRAINT MEDIA_TYPE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT MEDIA_TYPE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT MEDIA_TYPE_LUT_NN NOT NULL, + CONSTRAINT MEDIA_TYPE_PK PRIMARY KEY(MEDIA_TYPE_ID), + CONSTRAINT MEDIA_TYPE_MTN_UN UNIQUE(MEDIA_TYPE_NAME) +); +CREATE TABLE LOGICAL_LIBRARY( + LOGICAL_LIBRARY_ID BIGINT UNSIGNED CONSTRAINT LOGICAL_LIBRARY_LLI_NN NOT NULL, + LOGICAL_LIBRARY_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LLN_NN NOT NULL, + IS_DISABLED CHAR(1) DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT LOGICAL_LIBRARY_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT LOGICAL_LIBRARY_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT LOGICAL_LIBRARY_LUT_NN NOT NULL, + CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_ID), + CONSTRAINT LOGICAL_LIBRARY_LLN_UN UNIQUE(LOGICAL_LIBRARY_NAME), + CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1')) +); +CREATE TABLE TAPE( + VID VARCHAR(100) CONSTRAINT TAPE_V_NN NOT NULL, + MEDIA_TYPE_ID BIGINT UNSIGNED CONSTRAINT TAPE_MTID_NN NOT NULL, + VENDOR VARCHAR(100) CONSTRAINT TAPE_V2_NN NOT NULL, + LOGICAL_LIBRARY_ID BIGINT UNSIGNED CONSTRAINT TAPE_LLI_NN NOT NULL, + TAPE_POOL_ID BIGINT UNSIGNED CONSTRAINT TAPE_TPI_NN NOT NULL, + ENCRYPTION_KEY_NAME VARCHAR(100), + DATA_IN_BYTES BIGINT UNSIGNED CONSTRAINT TAPE_DIB_NN NOT NULL, + LAST_FSEQ BIGINT UNSIGNED CONSTRAINT TAPE_LF_NN NOT NULL, + NB_MASTER_FILES BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_NB_MASTER_FILES_NN NOT NULL, + MASTER_DATA_IN_BYTES BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_MASTER_DATA_IN_BYTES_NN NOT NULL, + IS_FULL CHAR(1) CONSTRAINT TAPE_IF_NN NOT NULL, + IS_FROM_CASTOR CHAR(1) CONSTRAINT TAPE_IFC_NN NOT NULL, + DIRTY CHAR(1) DEFAULT '1' CONSTRAINT TAPE_DIRTY_NN NOT NULL, + NB_COPY_NB_1 BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_1_NN NOT NULL, + COPY_NB_1_IN_BYTES BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_COPY_NB_1_IN_BYTES_NN NOT NULL, + NB_COPY_NB_GT_1 BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_GT_1_NN NOT NULL, + COPY_NB_GT_1_IN_BYTES BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_COPY_NB_GT_1_IN_BYTES_NN NOT NULL, + LABEL_DRIVE VARCHAR(100), + LABEL_TIME BIGINT UNSIGNED , + LAST_READ_DRIVE VARCHAR(100), + LAST_READ_TIME BIGINT UNSIGNED , + LAST_WRITE_DRIVE VARCHAR(100), + LAST_WRITE_TIME BIGINT UNSIGNED , + READ_MOUNT_COUNT BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL, + WRITE_MOUNT_COUNT BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL, + USER_COMMENT VARCHAR(1000), + TAPE_STATE VARCHAR(100) CONSTRAINT TAPE_TS_NN NOT NULL, + STATE_REASON VARCHAR(1000), + STATE_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT TAPE_SUT_NN NOT NULL, + STATE_MODIFIED_BY VARCHAR(100) CONSTRAINT TAPE_SMB_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT TAPE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT TAPE_LUT_NN NOT NULL, + CONSTRAINT TAPE_PK PRIMARY KEY(VID), + CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID), + CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), + CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1')), + CONSTRAINT TAPE_IS_FROM_CASTOR_BOOL_CK CHECK(IS_FROM_CASTOR IN ('0', '1')), + CONSTRAINT TAPE_DIRTY_BOOL_CK CHECK(DIRTY IN ('0','1')), + CONSTRAINT TAPE_STATE_CK CHECK(TAPE_STATE IN ('ACTIVE', 'DISABLED', 'BROKEN')), + CONSTRAINT TAPE_MEDIA_TYPE_FK FOREIGN KEY(MEDIA_TYPE_ID) REFERENCES MEDIA_TYPE(MEDIA_TYPE_ID) +); +CREATE INDEX TAPE_TAPE_POOL_ID_IDX ON TAPE(TAPE_POOL_ID); +CREATE INDEX TAPE_STATE_IDX ON TAPE(TAPE_STATE); +CREATE TABLE MOUNT_POLICY( + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_MPN_NN NOT NULL, + ARCHIVE_PRIORITY BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_AP_NN NOT NULL, + ARCHIVE_MIN_REQUEST_AGE BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_AMRA_NN NOT NULL, + RETRIEVE_PRIORITY BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_RP_NN NOT NULL, + RETRIEVE_MIN_REQUEST_AGE BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_RMRA_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT MOUNT_POLICY_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_LUT_NN NOT NULL, + CONSTRAINT MOUNT_POLICY_PK PRIMARY KEY(MOUNT_POLICY_NAME) +); +CREATE TABLE REQUESTER_MOUNT_RULE( + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_DIN_NN NOT NULL, + REQUESTER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_RN_NN NOT NULL, + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_MPN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_RULE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT RQSTER_RULE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT RQSTER_RULE_LUT_NN NOT NULL, + CONSTRAINT RQSTER_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_NAME), + CONSTRAINT RQSTER_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME) + REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME) +); +CREATE TABLE REQUESTER_GROUP_MOUNT_RULE( + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_DIN_NN NOT NULL, + REQUESTER_GROUP_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_RGN_NN NOT NULL, + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_MPN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_GRP_RULE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT RQSTER_GRP_RULE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT RQSTER_GRP_RULE_LUT_NN NOT NULL, + CONSTRAINT RQSTER_GRP_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_GROUP_NAME), + CONSTRAINT RQSTER_GRP_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME) + REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME) +); +CREATE TABLE ARCHIVE_FILE( + ARCHIVE_FILE_ID BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_AFI_NN NOT NULL, + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DIN_NN NOT NULL, + DISK_FILE_ID VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DFI_NN NOT NULL, + DISK_FILE_UID INT UNSIGNED CONSTRAINT ARCHIVE_FILE_DFUID_NN NOT NULL, + DISK_FILE_GID INT UNSIGNED CONSTRAINT ARCHIVE_FILE_DFGID_NN NOT NULL, + SIZE_IN_BYTES BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL, + CHECKSUM_BLOB VARBINARY(200), + CHECKSUM_ADLER32 INT UNSIGNED CONSTRAINT ARCHIVE_FILE_CB2_NN NOT NULL, + STORAGE_CLASS_ID BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL, + CREATION_TIME BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL, + RECONCILIATION_TIME BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL, + IS_DELETED CHAR(1) DEFAULT '0' CONSTRAINT ARCHIVE_FILE_ID_NN NOT NULL, + COLLOCATION_HINT VARCHAR(100), + CONSTRAINT ARCHIVE_FILE_PK PRIMARY KEY(ARCHIVE_FILE_ID), + CONSTRAINT ARCHIVE_FILE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID), + CONSTRAINT ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID), + CONSTRAINT ARCHIVE_FILE_ID_BOOL_CK CHECK(IS_DELETED IN ('0', '1')) +); +CREATE INDEX ARCHIVE_FILE_DIN_IDX ON ARCHIVE_FILE(DISK_INSTANCE_NAME); +CREATE INDEX ARCHIVE_FILE_DFI_IDX ON ARCHIVE_FILE(DISK_FILE_ID); +CREATE TABLE TAPE_FILE( + VID VARCHAR(100) CONSTRAINT TAPE_FILE_V_NN NOT NULL, + FSEQ BIGINT UNSIGNED CONSTRAINT TAPE_FILE_F_NN NOT NULL, + BLOCK_ID BIGINT UNSIGNED CONSTRAINT TAPE_FILE_BI_NN NOT NULL, + LOGICAL_SIZE_IN_BYTES BIGINT UNSIGNED CONSTRAINT TAPE_FILE_CSIB_NN NOT NULL, + COPY_NB TINYINT UNSIGNED CONSTRAINT TAPE_FILE_CN_NN NOT NULL, + CREATION_TIME BIGINT UNSIGNED CONSTRAINT TAPE_FILE_CT_NN NOT NULL, + ARCHIVE_FILE_ID BIGINT UNSIGNED CONSTRAINT TAPE_FILE_AFI_NN NOT NULL, + CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ), + CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID) + REFERENCES TAPE(VID), + CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID) + REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID), + CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID), + CONSTRAINT TAPE_FILE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0) +); +CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID); +CREATE INDEX TAPE_FILE_ARCHIVE_FILE_ID_IDX ON TAPE_FILE(ARCHIVE_FILE_ID); +CREATE TABLE ACTIVITIES_WEIGHTS ( + DISK_INSTANCE_NAME VARCHAR(100), + ACTIVITY VARCHAR(100), + WEIGHT VARCHAR(100), + USER_COMMENT VARCHAR(1000) CONSTRAINT ACTIV_WEIGHTS_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLHN_NN NOT NULL, + CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT ACTIV_WEIGHTS_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUHN_NN NOT NULL, + LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT ACTIV_WEIGHTS_LUT_NN NOT NULL +); +CREATE TABLE FILE_RECYCLE_LOG( + FILE_RECYCLE_LOG_ID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_ID_NN NOT NULL, + VID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_VID_NN NOT NULL, + FSEQ BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_FSEQ_NN NOT NULL, + BLOCK_ID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_BID_NN NOT NULL, + COPY_NB TINYINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_COPY_NB_NN NOT NULL, + TAPE_FILE_CREATION_TIME BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_TFCT_NN NOT NULL, + ARCHIVE_FILE_ID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_AFI_NN NOT NULL, + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DIN_NN NOT NULL, + DISK_FILE_ID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFI_NN NOT NULL, + DISK_FILE_ID_WHEN_DELETED VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFIWD_NN NOT NULL, + DISK_FILE_UID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_DFU_NN NOT NULL, + DISK_FILE_GID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_DFG_NN NOT NULL, + SIZE_IN_BYTES BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_SIB_NN NOT NULL, + CHECKSUM_BLOB VARBINARY(200), + CHECKSUM_ADLER32 INT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_CA_NN NOT NULL, + STORAGE_CLASS_ID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_SCI_NN NOT NULL, + ARCHIVE_FILE_CREATION_TIME BIGINT UNSIGNED CONSTRAINT FILE_RECYLE_LOG_CT_NN NOT NULL, + RECONCILIATION_TIME BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_RT_NN NOT NULL, + COLLOCATION_HINT VARCHAR(100), + DISK_FILE_PATH VARCHAR(2000), + REASON_LOG VARCHAR(1000) CONSTRAINT FILE_RECYCLE_LOG_RL_NN NOT NULL, + RECYCLE_LOG_TIME BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_RLT_NN NOT NULL, + CONSTRAINT FILE_RECYCLE_LOG_PK PRIMARY KEY(FILE_RECYCLE_LOG_ID), + CONSTRAINT FILE_RECYCLE_LOG_VID_FK FOREIGN KEY(VID) REFERENCES TAPE(VID), + CONSTRAINT FILE_RECYCLE_LOG_SC_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID) +); +CREATE INDEX FILE_RECYCLE_LOG_DFI_IDX ON FILE_RECYCLE_LOG(DISK_FILE_ID); + +CREATE TABLE DRIVE_CONFIG ( + DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_DN_NN NOT NULL, + CATEGORY VARCHAR(100) CONSTRAINT DRIVE_CONFIG_C_NN NOT NULL, + KEY_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_KN_NN NOT NULL, + VALUE VARCHAR(1000) CONSTRAINT DRIVE_CONFIG_V_NN NOT NULL, + SOURCE VARCHAR(100) CONSTRAINT DRIVE_CONFIG_S_NN NOT NULL, + CONSTRAINT DRIVE_CONFIG_DN_PK PRIMARY KEY(KEY_NAME, DRIVE_NAME) +); + +CREATE TABLE TAPE_DRIVE ( + DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DN_NN NOT NULL, + HOST VARCHAR(100) CONSTRAINT DRIVE_STATE_H_NN NOT NULL, + LOGICAL_LIBRARY VARCHAR(100) CONSTRAINT DRIVE_STATE_LL_NN NOT NULL, + SESSION_ID BIGINT UNSIGNED, + BYTES_TRANSFERED_IN_SESSION BIGINT UNSIGNED, + FILES_TRANSFERED_IN_SESSION BIGINT UNSIGNED, + LATEST_BANDWIDTH VARCHAR(100), + SESSION_START_TIME BIGINT UNSIGNED, + MOUNT_START_TIME BIGINT UNSIGNED, + TRANSFER_START_TIME BIGINT UNSIGNED, + UNLOAD_START_TIME BIGINT UNSIGNED, + UNMOUNT_START_TIME BIGINT UNSIGNED, + DRAINING_START_TIME BIGINT UNSIGNED, + DOWN_OR_UP_START_TIME BIGINT UNSIGNED, + PROBE_START_TIME BIGINT UNSIGNED, + CLEANUP_START_TIME BIGINT UNSIGNED, + START_START_TIME BIGINT UNSIGNED, + SHUTDOWN_TIME BIGINT UNSIGNED, + MOUNT_TYPE INT UNSIGNED CONSTRAINT DRIVE_STATE_MT_NN NOT NULL, + DRIVE_STATUS VARCHAR(100) DEFAULT 'UNKNOWN' CONSTRAINT DRIVE_STATE_DS_NN NOT NULL, + DESIRED_UP CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DU_NN NOT NULL, + DESIRED_FORCE_DOWN CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DFD_NN NOT NULL, + REASON_UP_DOWN VARCHAR(1000), + CURRENT_VID VARCHAR(100), + CTA_VERSION VARCHAR(100), + CURRENT_PRIORITY BIGINT UNSIGNED, + CURRENT_ACTIVITY VARCHAR(100), + CURRENT_ACTIVITY_WEIGHT VARCHAR(100), + CURRENT_TAPE_POOL VARCHAR(100), + NEXT_MOUNT_TYPE INT UNSIGNED, + NEXT_VID VARCHAR(100), + NEXT_TAPE_POOL VARCHAR(100), + NEXT_PRIORITY BIGINT UNSIGNED, + NEXT_ACTIVITY VARCHAR(100), + NEXT_ACTIVITY_WEIGHT VARCHAR(100), + DEV_FILE_NAME VARCHAR(100), + RAW_LIBRARY_SLOT VARCHAR(100), + CURRENT_VO VARCHAR(100), + NEXT_VO VARCHAR(100), + USER_COMMENT VARCHAR(1000), + CREATION_LOG_USER_NAME VARCHAR(100), + CREATION_LOG_HOST_NAME VARCHAR(100), + CREATION_LOG_TIME BIGINT UNSIGNED, + LAST_UPDATE_USER_NAME VARCHAR(100), + LAST_UPDATE_HOST_NAME VARCHAR(100), + LAST_UPDATE_TIME BIGINT UNSIGNED, + DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DSN_NN NOT NULL, + RESERVED_BYTES BIGINT UNSIGNED CONSTRAINT DRIVE_STATE_RB_NN NOT NULL, + CONSTRAINT DRIVE_STATE_DN_PK PRIMARY KEY(DRIVE_NAME), + CONSTRAINT DRIVE_STATE_DU_BOOL_CK CHECK(DESIRED_UP IN ('0', '1')), + CONSTRAINT DRIVE_STATE_DFD_BOOL_CK CHECK(DESIRED_FORCE_DOWN IN ('0', '1')), + CONSTRAINT DRIVE_STATE_DS_STRING_CK CHECK(DRIVE_STATUS IN ('DOWN', 'UP', 'PROBING', 'STARTING', + 'MOUNTING', 'TRANSFERING', 'UNLOADING', 'UNMOUNTING', 'DRAININGTODISK', 'CLEANINGUP', 'SHUTDOWN', + 'UNKNOWN')) +); +INSERT INTO CTA_CATALOGUE( + SCHEMA_VERSION_MAJOR, + SCHEMA_VERSION_MINOR, + STATUS) +VALUES( + 4, + 2, + 'PRODUCTION'); +ALTER TABLE CTA_CATALOGUE ADD CONSTRAINT + CATALOGUE_STATUS_CONTENT_CK CHECK((NEXT_SCHEMA_VERSION_MAJOR IS NULL AND NEXT_SCHEMA_VERSION_MINOR IS NULL AND STATUS='PRODUCTION') OR (STATUS='UPGRADING')); diff --git a/catalogue/4.2/oracle_catalogue_schema.sql b/catalogue/4.2/oracle_catalogue_schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..279281b840908aab7a79b27636aef9c5de4f058c --- /dev/null +++ b/catalogue/4.2/oracle_catalogue_schema.sql @@ -0,0 +1,455 @@ +CREATE SEQUENCE ARCHIVE_FILE_ID_SEQ + INCREMENT BY 1 + START WITH 4294967296 + NOMAXVALUE + MINVALUE 1 + NOCYCLE + CACHE 20 + NOORDER; +CREATE SEQUENCE LOGICAL_LIBRARY_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NOMAXVALUE + MINVALUE 1 + NOCYCLE + CACHE 20 + NOORDER; +CREATE SEQUENCE MEDIA_TYPE_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NOMAXVALUE + MINVALUE 1 + NOCYCLE + CACHE 20 + NOORDER; +CREATE SEQUENCE STORAGE_CLASS_ID_SEQ + INCREMENT BY 1 + START WITH 10000 + NOMAXVALUE + MINVALUE 1 + NOCYCLE + CACHE 20 + NOORDER; +CREATE SEQUENCE TAPE_POOL_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NOMAXVALUE + MINVALUE 1 + NOCYCLE + CACHE 20 + NOORDER; +CREATE SEQUENCE VIRTUAL_ORGANIZATION_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NOMAXVALUE + MINVALUE 1 + NOCYCLE + CACHE 20 + NOORDER; +CREATE SEQUENCE FILE_RECYCLE_LOG_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NOMAXVALUE + MINVALUE 1 + NOCYCLE + CACHE 20 + NOORDER; +CREATE GLOBAL TEMPORARY TABLE TEMP_TAPE_FILE_INSERTION_BATCH( + VID VARCHAR2(100), + FSEQ NUMERIC(20, 0) , + BLOCK_ID NUMERIC(20, 0) , + LOGICAL_SIZE_IN_BYTES NUMERIC(20, 0) , + COPY_NB NUMERIC(3, 0) , + CREATION_TIME NUMERIC(20, 0) , + ARCHIVE_FILE_ID NUMERIC(20, 0) +) +ON COMMIT DELETE ROWS; +CREATE INDEX TEMP_T_F_I_B_AFI_IDX ON TEMP_TAPE_FILE_INSERTION_BATCH(ARCHIVE_FILE_ID); +CREATE TABLE CTA_CATALOGUE( + SCHEMA_VERSION_MAJOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM1_NN NOT NULL, + SCHEMA_VERSION_MINOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL, + NEXT_SCHEMA_VERSION_MAJOR NUMERIC(20, 0), + NEXT_SCHEMA_VERSION_MINOR NUMERIC(20, 0), + STATUS VARCHAR2(100), + IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL, + CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1')) +); +CREATE TABLE ADMIN_USER( + ADMIN_USER_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT ADMIN_USER_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ADMIN_USER_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ADMIN_USER_LUT_NN NOT NULL, + CONSTRAINT ADMIN_USER_PK PRIMARY KEY(ADMIN_USER_NAME) +); +CREATE TABLE DISK_SYSTEM( + DISK_SYSTEM_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_DSNM_NN NOT NULL, + FILE_REGEXP VARCHAR2(100) CONSTRAINT DISK_SYSTEM_FR_NN NOT NULL, + FREE_SPACE_QUERY_URL VARCHAR2(1000) CONSTRAINT DISK_SYSTEM_FSQU_NN NOT NULL, + REFRESH_INTERVAL NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_RI_NN NOT NULL, + TARGETED_FREE_SPACE NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_TFS_NN NOT NULL, + SLEEP_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_ST_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT DISK_SYSTEM_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_LUT_NN NOT NULL, + CONSTRAINT NAME_PK PRIMARY KEY(DISK_SYSTEM_NAME) +); +CREATE TABLE VIRTUAL_ORGANIZATION( + VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_VOI_NN NOT NULL, + VIRTUAL_ORGANIZATION_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL, + READ_MAX_DRIVES NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL, + WRITE_MAX_DRIVES NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL, + MAX_FILE_SIZE NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_LUT_NN NOT NULL, + CONSTRAINT VIRTUAL_ORGANIZATION_PK PRIMARY KEY(VIRTUAL_ORGANIZATION_ID), + CONSTRAINT VIRTUAL_ORGANIZATION_VON_UN UNIQUE(VIRTUAL_ORGANIZATION_NAME) +); +CREATE TABLE STORAGE_CLASS( + STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_SCI_NN NOT NULL, + STORAGE_CLASS_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_SCN_NN NOT NULL, + NB_COPIES NUMERIC(3, 0) CONSTRAINT STORAGE_CLASS_NC_NN NOT NULL, + VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_VOI_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT STORAGE_CLASS_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_LUT_NN NOT NULL, + CONSTRAINT STORAGE_CLASS_PK PRIMARY KEY(STORAGE_CLASS_ID), + CONSTRAINT STORAGE_CLASS_SCN_UN UNIQUE(STORAGE_CLASS_NAME), + CONSTRAINT STORAGE_CLASS_VOI_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID) +); +CREATE TABLE TAPE_POOL( + TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT TAPE_POOL_TPI_NN NOT NULL, + TAPE_POOL_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_TPN_NN NOT NULL, + VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT TAPE_POOL_VOI_NN NOT NULL, + NB_PARTIAL_TAPES NUMERIC(20, 0) CONSTRAINT TAPE_POOL_NPT_NN NOT NULL, + IS_ENCRYPTED CHAR(1) CONSTRAINT TAPE_POOL_IE_NN NOT NULL, + SUPPLY VARCHAR2(100), + USER_COMMENT VARCHAR2(1000) CONSTRAINT TAPE_POOL_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT TAPE_POOL_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_POOL_LUT_NN NOT NULL, + CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_ID), + CONSTRAINT TAPE_POOL_TPN_UN UNIQUE(TAPE_POOL_NAME), + CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1')), + CONSTRAINT TAPE_POOL_VO_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID) +); +CREATE TABLE ARCHIVE_ROUTE( + STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_SCI_NN NOT NULL, + COPY_NB NUMERIC(3, 0) CONSTRAINT ARCHIVE_ROUTE_CN_NN NOT NULL, + TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_TPI_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT ARCHIVE_ROUTE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_ROUTE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_ROUTE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_ROUTE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_ROUTE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_LUT_NN NOT NULL, + CONSTRAINT ARCHIVE_ROUTE_PK PRIMARY KEY(STORAGE_CLASS_ID, COPY_NB), + CONSTRAINT ARCHIVE_ROUTE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID), + CONSTRAINT ARCHIVE_ROUTE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), + CONSTRAINT ARCHIVE_ROUTE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0), + CONSTRAINT ARCHIVE_ROUTE_SCI_TPI_UN UNIQUE(STORAGE_CLASS_ID, TAPE_POOL_ID) +); +CREATE TABLE MEDIA_TYPE( + MEDIA_TYPE_ID NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_MTI_NN NOT NULL, + MEDIA_TYPE_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_MTN_NN NOT NULL, + CARTRIDGE VARCHAR2(100) CONSTRAINT MEDIA_TYPE_C_NN NOT NULL, + CAPACITY_IN_BYTES NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_CIB_NN NOT NULL, + PRIMARY_DENSITY_CODE NUMERIC(3, 0), + SECONDARY_DENSITY_CODE NUMERIC(3, 0), + NB_WRAPS NUMERIC(10, 0), + MIN_LPOS NUMERIC(20, 0), + MAX_LPOS NUMERIC(20, 0), + USER_COMMENT VARCHAR2(1000) CONSTRAINT MEDIA_TYPE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_LUT_NN NOT NULL, + CONSTRAINT MEDIA_TYPE_PK PRIMARY KEY(MEDIA_TYPE_ID), + CONSTRAINT MEDIA_TYPE_MTN_UN UNIQUE(MEDIA_TYPE_NAME) +); +CREATE TABLE LOGICAL_LIBRARY( + LOGICAL_LIBRARY_ID NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_LLI_NN NOT NULL, + LOGICAL_LIBRARY_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_LLN_NN NOT NULL, + IS_DISABLED CHAR(1) DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT LOGICAL_LIBRARY_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_LUT_NN NOT NULL, + CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_ID), + CONSTRAINT LOGICAL_LIBRARY_LLN_UN UNIQUE(LOGICAL_LIBRARY_NAME), + CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1')) +); +CREATE TABLE TAPE( + VID VARCHAR2(100) CONSTRAINT TAPE_V_NN NOT NULL, + MEDIA_TYPE_ID NUMERIC(20, 0) CONSTRAINT TAPE_MTID_NN NOT NULL, + VENDOR VARCHAR2(100) CONSTRAINT TAPE_V2_NN NOT NULL, + LOGICAL_LIBRARY_ID NUMERIC(20, 0) CONSTRAINT TAPE_LLI_NN NOT NULL, + TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT TAPE_TPI_NN NOT NULL, + ENCRYPTION_KEY_NAME VARCHAR2(100), + DATA_IN_BYTES NUMERIC(20, 0) CONSTRAINT TAPE_DIB_NN NOT NULL, + LAST_FSEQ NUMERIC(20, 0) CONSTRAINT TAPE_LF_NN NOT NULL, + NB_MASTER_FILES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_MASTER_FILES_NN NOT NULL, + MASTER_DATA_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_MASTER_DATA_IN_BYTES_NN NOT NULL, + IS_FULL CHAR(1) CONSTRAINT TAPE_IF_NN NOT NULL, + IS_FROM_CASTOR CHAR(1) CONSTRAINT TAPE_IFC_NN NOT NULL, + DIRTY CHAR(1) DEFAULT '1' CONSTRAINT TAPE_DIRTY_NN NOT NULL, + NB_COPY_NB_1 NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_1_NN NOT NULL, + COPY_NB_1_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_COPY_NB_1_IN_BYTES_NN NOT NULL, + NB_COPY_NB_GT_1 NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_GT_1_NN NOT NULL, + COPY_NB_GT_1_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_COPY_NB_GT_1_IN_BYTES_NN NOT NULL, + LABEL_DRIVE VARCHAR2(100), + LABEL_TIME NUMERIC(20, 0) , + LAST_READ_DRIVE VARCHAR2(100), + LAST_READ_TIME NUMERIC(20, 0) , + LAST_WRITE_DRIVE VARCHAR2(100), + LAST_WRITE_TIME NUMERIC(20, 0) , + READ_MOUNT_COUNT NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL, + WRITE_MOUNT_COUNT NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL, + USER_COMMENT VARCHAR2(1000), + TAPE_STATE VARCHAR2(100) CONSTRAINT TAPE_TS_NN NOT NULL, + STATE_REASON VARCHAR2(1000), + STATE_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_SUT_NN NOT NULL, + STATE_MODIFIED_BY VARCHAR2(100) CONSTRAINT TAPE_SMB_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT TAPE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_LUT_NN NOT NULL, + CONSTRAINT TAPE_PK PRIMARY KEY(VID), + CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID), + CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), + CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1')), + CONSTRAINT TAPE_IS_FROM_CASTOR_BOOL_CK CHECK(IS_FROM_CASTOR IN ('0', '1')), + CONSTRAINT TAPE_DIRTY_BOOL_CK CHECK(DIRTY IN ('0','1')), + CONSTRAINT TAPE_STATE_CK CHECK(TAPE_STATE IN ('ACTIVE', 'DISABLED', 'BROKEN')), + CONSTRAINT TAPE_MEDIA_TYPE_FK FOREIGN KEY(MEDIA_TYPE_ID) REFERENCES MEDIA_TYPE(MEDIA_TYPE_ID) +); +CREATE INDEX TAPE_TAPE_POOL_ID_IDX ON TAPE(TAPE_POOL_ID); +CREATE INDEX TAPE_STATE_IDX ON TAPE(TAPE_STATE); +CREATE TABLE MOUNT_POLICY( + MOUNT_POLICY_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_MPN_NN NOT NULL, + ARCHIVE_PRIORITY NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_AP_NN NOT NULL, + ARCHIVE_MIN_REQUEST_AGE NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_AMRA_NN NOT NULL, + RETRIEVE_PRIORITY NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_RP_NN NOT NULL, + RETRIEVE_MIN_REQUEST_AGE NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_RMRA_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT MOUNT_POLICY_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_LUT_NN NOT NULL, + CONSTRAINT MOUNT_POLICY_PK PRIMARY KEY(MOUNT_POLICY_NAME) +); +CREATE TABLE REQUESTER_MOUNT_RULE( + DISK_INSTANCE_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_DIN_NN NOT NULL, + REQUESTER_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_RN_NN NOT NULL, + MOUNT_POLICY_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_MPN_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT RQSTER_RULE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_RULE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_RULE_LUT_NN NOT NULL, + CONSTRAINT RQSTER_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_NAME), + CONSTRAINT RQSTER_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME) + REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME) +); +CREATE TABLE REQUESTER_GROUP_MOUNT_RULE( + DISK_INSTANCE_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_DIN_NN NOT NULL, + REQUESTER_GROUP_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_RGN_NN NOT NULL, + MOUNT_POLICY_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_MPN_NN NOT NULL, + USER_COMMENT VARCHAR2(1000) CONSTRAINT RQSTER_GRP_RULE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_GRP_RULE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_GRP_RULE_LUT_NN NOT NULL, + CONSTRAINT RQSTER_GRP_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_GROUP_NAME), + CONSTRAINT RQSTER_GRP_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME) + REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME) +); +CREATE TABLE ARCHIVE_FILE( + ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_AFI_NN NOT NULL, + DISK_INSTANCE_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_FILE_DIN_NN NOT NULL, + DISK_FILE_ID VARCHAR2(100) CONSTRAINT ARCHIVE_FILE_DFI_NN NOT NULL, + DISK_FILE_UID NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_DFUID_NN NOT NULL, + DISK_FILE_GID NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_DFGID_NN NOT NULL, + SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL, + CHECKSUM_BLOB RAW(200), + CHECKSUM_ADLER32 NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_CB2_NN NOT NULL, + STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL, + CREATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL, + RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL, + IS_DELETED CHAR(1) DEFAULT '0' CONSTRAINT ARCHIVE_FILE_ID_NN NOT NULL, + COLLOCATION_HINT VARCHAR2(100), + CONSTRAINT ARCHIVE_FILE_PK PRIMARY KEY(ARCHIVE_FILE_ID), + CONSTRAINT ARCHIVE_FILE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID), + CONSTRAINT ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID), + CONSTRAINT ARCHIVE_FILE_ID_BOOL_CK CHECK(IS_DELETED IN ('0', '1')) +); +CREATE INDEX ARCHIVE_FILE_DIN_IDX ON ARCHIVE_FILE(DISK_INSTANCE_NAME); +CREATE INDEX ARCHIVE_FILE_DFI_IDX ON ARCHIVE_FILE(DISK_FILE_ID); +CREATE TABLE TAPE_FILE( + VID VARCHAR2(100) CONSTRAINT TAPE_FILE_V_NN NOT NULL, + FSEQ NUMERIC(20, 0) CONSTRAINT TAPE_FILE_F_NN NOT NULL, + BLOCK_ID NUMERIC(20, 0) CONSTRAINT TAPE_FILE_BI_NN NOT NULL, + LOGICAL_SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CSIB_NN NOT NULL, + COPY_NB NUMERIC(3, 0) CONSTRAINT TAPE_FILE_CN_NN NOT NULL, + CREATION_TIME NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CT_NN NOT NULL, + ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT TAPE_FILE_AFI_NN NOT NULL, + CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ), + CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID) + REFERENCES TAPE(VID), + CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID) + REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID), + CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID), + CONSTRAINT TAPE_FILE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0) +); +CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID); +CREATE INDEX TAPE_FILE_ARCHIVE_FILE_ID_IDX ON TAPE_FILE(ARCHIVE_FILE_ID); +CREATE TABLE ACTIVITIES_WEIGHTS ( + DISK_INSTANCE_NAME VARCHAR2(100), + ACTIVITY VARCHAR2(100), + WEIGHT VARCHAR2(100), + USER_COMMENT VARCHAR2(1000) CONSTRAINT ACTIV_WEIGHTS_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT ACTIV_WEIGHTS_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT ACTIV_WEIGHTS_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ACTIV_WEIGHTS_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT ACTIV_WEIGHTS_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT ACTIV_WEIGHTS_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ACTIV_WEIGHTS_LUT_NN NOT NULL +); +CREATE TABLE FILE_RECYCLE_LOG( + FILE_RECYCLE_LOG_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_ID_NN NOT NULL, + VID VARCHAR2(100) CONSTRAINT FILE_RECYCLE_LOG_VID_NN NOT NULL, + FSEQ NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_FSEQ_NN NOT NULL, + BLOCK_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_BID_NN NOT NULL, + COPY_NB NUMERIC(3, 0) CONSTRAINT FILE_RECYCLE_LOG_COPY_NB_NN NOT NULL, + TAPE_FILE_CREATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_TFCT_NN NOT NULL, + ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_AFI_NN NOT NULL, + DISK_INSTANCE_NAME VARCHAR2(100) CONSTRAINT FILE_RECYCLE_LOG_DIN_NN NOT NULL, + DISK_FILE_ID VARCHAR2(100) CONSTRAINT FILE_RECYCLE_LOG_DFI_NN NOT NULL, + DISK_FILE_ID_WHEN_DELETED VARCHAR2(100) CONSTRAINT FILE_RECYCLE_LOG_DFIWD_NN NOT NULL, + DISK_FILE_UID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_DFU_NN NOT NULL, + DISK_FILE_GID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_DFG_NN NOT NULL, + SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_SIB_NN NOT NULL, + CHECKSUM_BLOB RAW(200), + CHECKSUM_ADLER32 NUMERIC(10, 0) CONSTRAINT FILE_RECYCLE_LOG_CA_NN NOT NULL, + STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_SCI_NN NOT NULL, + ARCHIVE_FILE_CREATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYLE_LOG_CT_NN NOT NULL, + RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_RT_NN NOT NULL, + COLLOCATION_HINT VARCHAR2(100), + DISK_FILE_PATH VARCHAR2(2000), + REASON_LOG VARCHAR2(1000) CONSTRAINT FILE_RECYCLE_LOG_RL_NN NOT NULL, + RECYCLE_LOG_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_RLT_NN NOT NULL, + CONSTRAINT FILE_RECYCLE_LOG_PK PRIMARY KEY(FILE_RECYCLE_LOG_ID), + CONSTRAINT FILE_RECYCLE_LOG_VID_FK FOREIGN KEY(VID) REFERENCES TAPE(VID), + CONSTRAINT FILE_RECYCLE_LOG_SC_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID) +); +CREATE INDEX FILE_RECYCLE_LOG_DFI_IDX ON FILE_RECYCLE_LOG(DISK_FILE_ID); + +CREATE TABLE DRIVE_CONFIG ( + DRIVE_NAME VARCHAR2(100) CONSTRAINT DRIVE_CONFIG_DN_NN NOT NULL, + CATEGORY VARCHAR2(100) CONSTRAINT DRIVE_CONFIG_C_NN NOT NULL, + KEY_NAME VARCHAR2(100) CONSTRAINT DRIVE_CONFIG_KN_NN NOT NULL, + VALUE VARCHAR2(1000) CONSTRAINT DRIVE_CONFIG_V_NN NOT NULL, + SOURCE VARCHAR2(100) CONSTRAINT DRIVE_CONFIG_S_NN NOT NULL, + CONSTRAINT DRIVE_CONFIG_DN_PK PRIMARY KEY(KEY_NAME, DRIVE_NAME) +); + +CREATE TABLE TAPE_DRIVE ( + DRIVE_NAME VARCHAR2(100) CONSTRAINT DRIVE_STATE_DN_NN NOT NULL, + HOST VARCHAR2(100) CONSTRAINT DRIVE_STATE_H_NN NOT NULL, + LOGICAL_LIBRARY VARCHAR2(100) CONSTRAINT DRIVE_STATE_LL_NN NOT NULL, + SESSION_ID NUMERIC(20, 0), + BYTES_TRANSFERED_IN_SESSION NUMERIC(20, 0), + FILES_TRANSFERED_IN_SESSION NUMERIC(20, 0), + LATEST_BANDWIDTH VARCHAR2(100), + SESSION_START_TIME NUMERIC(20, 0), + MOUNT_START_TIME NUMERIC(20, 0), + TRANSFER_START_TIME NUMERIC(20, 0), + UNLOAD_START_TIME NUMERIC(20, 0), + UNMOUNT_START_TIME NUMERIC(20, 0), + DRAINING_START_TIME NUMERIC(20, 0), + DOWN_OR_UP_START_TIME NUMERIC(20, 0), + PROBE_START_TIME NUMERIC(20, 0), + CLEANUP_START_TIME NUMERIC(20, 0), + START_START_TIME NUMERIC(20, 0), + SHUTDOWN_TIME NUMERIC(20, 0), + MOUNT_TYPE NUMERIC(10, 0) CONSTRAINT DRIVE_STATE_MT_NN NOT NULL, + DRIVE_STATUS VARCHAR2(100) DEFAULT 'UNKNOWN' CONSTRAINT DRIVE_STATE_DS_NN NOT NULL, + DESIRED_UP CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DU_NN NOT NULL, + DESIRED_FORCE_DOWN CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DFD_NN NOT NULL, + REASON_UP_DOWN VARCHAR2(1000), + CURRENT_VID VARCHAR2(100), + CTA_VERSION VARCHAR2(100), + CURRENT_PRIORITY NUMERIC(20, 0), + CURRENT_ACTIVITY VARCHAR2(100), + CURRENT_ACTIVITY_WEIGHT VARCHAR2(100), + CURRENT_TAPE_POOL VARCHAR2(100), + NEXT_MOUNT_TYPE NUMERIC(10, 0), + NEXT_VID VARCHAR2(100), + NEXT_TAPE_POOL VARCHAR2(100), + NEXT_PRIORITY NUMERIC(20, 0), + NEXT_ACTIVITY VARCHAR2(100), + NEXT_ACTIVITY_WEIGHT VARCHAR2(100), + DEV_FILE_NAME VARCHAR2(100), + RAW_LIBRARY_SLOT VARCHAR2(100), + CURRENT_VO VARCHAR2(100), + NEXT_VO VARCHAR2(100), + USER_COMMENT VARCHAR2(1000), + CREATION_LOG_USER_NAME VARCHAR2(100), + CREATION_LOG_HOST_NAME VARCHAR2(100), + CREATION_LOG_TIME NUMERIC(20, 0), + LAST_UPDATE_USER_NAME VARCHAR2(100), + LAST_UPDATE_HOST_NAME VARCHAR2(100), + LAST_UPDATE_TIME NUMERIC(20, 0), + DISK_SYSTEM_NAME VARCHAR2(100) CONSTRAINT DRIVE_STATE_DSN_NN NOT NULL, + RESERVED_BYTES NUMERIC(20, 0) CONSTRAINT DRIVE_STATE_RB_NN NOT NULL, + CONSTRAINT DRIVE_STATE_DN_PK PRIMARY KEY(DRIVE_NAME), + CONSTRAINT DRIVE_STATE_DU_BOOL_CK CHECK(DESIRED_UP IN ('0', '1')), + CONSTRAINT DRIVE_STATE_DFD_BOOL_CK CHECK(DESIRED_FORCE_DOWN IN ('0', '1')), + CONSTRAINT DRIVE_STATE_DS_STRING_CK CHECK(DRIVE_STATUS IN ('DOWN', 'UP', 'PROBING', 'STARTING', + 'MOUNTING', 'TRANSFERING', 'UNLOADING', 'UNMOUNTING', 'DRAININGTODISK', 'CLEANINGUP', 'SHUTDOWN', + 'UNKNOWN')) +); +INSERT INTO CTA_CATALOGUE( + SCHEMA_VERSION_MAJOR, + SCHEMA_VERSION_MINOR, + STATUS) +VALUES( + 4, + 2, + 'PRODUCTION'); +ALTER TABLE CTA_CATALOGUE ADD CONSTRAINT CATALOGUE_STATUS_CONTENT_CK CHECK((NEXT_SCHEMA_VERSION_MAJOR IS NULL AND NEXT_SCHEMA_VERSION_MINOR IS NULL AND STATUS='PRODUCTION') OR (NEXT_SCHEMA_VERSION_MAJOR IS NOT NULL AND NEXT_SCHEMA_VERSION_MINOR IS NOT NULL AND STATUS='UPGRADING')) INITIALLY DEFERRED; + +COMMIT; diff --git a/catalogue/4.2/postgres_catalogue_schema.sql b/catalogue/4.2/postgres_catalogue_schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..fcd0ab2f91a54fcc388ba9a6c323114692ad7dc7 --- /dev/null +++ b/catalogue/4.2/postgres_catalogue_schema.sql @@ -0,0 +1,440 @@ +CREATE SEQUENCE ARCHIVE_FILE_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NO MAXVALUE + MINVALUE 1 + NO CYCLE + CACHE 20; +CREATE SEQUENCE LOGICAL_LIBRARY_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NO MAXVALUE + MINVALUE 1 + NO CYCLE + CACHE 20; +CREATE SEQUENCE MEDIA_TYPE_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NO MAXVALUE + MINVALUE 1 + NO CYCLE + CACHE 20; +CREATE SEQUENCE STORAGE_CLASS_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NO MAXVALUE + MINVALUE 1 + NO CYCLE + CACHE 20; +CREATE SEQUENCE TAPE_POOL_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NO MAXVALUE + MINVALUE 1 + NO CYCLE + CACHE 20; +CREATE SEQUENCE VIRTUAL_ORGANIZATION_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NO MAXVALUE + MINVALUE 1 + NO CYCLE + CACHE 20; +CREATE SEQUENCE FILE_RECYCLE_LOG_ID_SEQ + INCREMENT BY 1 + START WITH 1 + NO MAXVALUE + MINVALUE 1 + NO CYCLE + CACHE 20; +CREATE TABLE CTA_CATALOGUE( + SCHEMA_VERSION_MAJOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM1_NN NOT NULL, + SCHEMA_VERSION_MINOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL, + NEXT_SCHEMA_VERSION_MAJOR NUMERIC(20, 0), + NEXT_SCHEMA_VERSION_MINOR NUMERIC(20, 0), + STATUS VARCHAR(100), + IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL, + CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1')) +); +CREATE TABLE ADMIN_USER( + ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT ADMIN_USER_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ADMIN_USER_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ADMIN_USER_LUT_NN NOT NULL, + CONSTRAINT ADMIN_USER_PK PRIMARY KEY(ADMIN_USER_NAME) +); +CREATE TABLE DISK_SYSTEM( + DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_DSNM_NN NOT NULL, + FILE_REGEXP VARCHAR(100) CONSTRAINT DISK_SYSTEM_FR_NN NOT NULL, + FREE_SPACE_QUERY_URL VARCHAR(1000) CONSTRAINT DISK_SYSTEM_FSQU_NN NOT NULL, + REFRESH_INTERVAL NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_RI_NN NOT NULL, + TARGETED_FREE_SPACE NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_TFS_NN NOT NULL, + SLEEP_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_ST_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT DISK_SYSTEM_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_LUT_NN NOT NULL, + CONSTRAINT NAME_PK PRIMARY KEY(DISK_SYSTEM_NAME) +); +CREATE TABLE VIRTUAL_ORGANIZATION( + VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_VOI_NN NOT NULL, + VIRTUAL_ORGANIZATION_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL, + READ_MAX_DRIVES NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL, + WRITE_MAX_DRIVES NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL, + MAX_FILE_SIZE NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_LUT_NN NOT NULL, + CONSTRAINT VIRTUAL_ORGANIZATION_PK PRIMARY KEY(VIRTUAL_ORGANIZATION_ID), + CONSTRAINT VIRTUAL_ORGANIZATION_VON_UN UNIQUE(VIRTUAL_ORGANIZATION_NAME) +); +CREATE TABLE STORAGE_CLASS( + STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_SCI_NN NOT NULL, + STORAGE_CLASS_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_SCN_NN NOT NULL, + NB_COPIES NUMERIC(3, 0) CONSTRAINT STORAGE_CLASS_NC_NN NOT NULL, + VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_VOI_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT STORAGE_CLASS_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_LUT_NN NOT NULL, + CONSTRAINT STORAGE_CLASS_PK PRIMARY KEY(STORAGE_CLASS_ID), + CONSTRAINT STORAGE_CLASS_SCN_UN UNIQUE(STORAGE_CLASS_NAME), + CONSTRAINT STORAGE_CLASS_VOI_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID) +); +CREATE TABLE TAPE_POOL( + TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT TAPE_POOL_TPI_NN NOT NULL, + TAPE_POOL_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_TPN_NN NOT NULL, + VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT TAPE_POOL_VOI_NN NOT NULL, + NB_PARTIAL_TAPES NUMERIC(20, 0) CONSTRAINT TAPE_POOL_NPT_NN NOT NULL, + IS_ENCRYPTED CHAR(1) CONSTRAINT TAPE_POOL_IE_NN NOT NULL, + SUPPLY VARCHAR(100), + USER_COMMENT VARCHAR(1000) CONSTRAINT TAPE_POOL_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT TAPE_POOL_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_POOL_LUT_NN NOT NULL, + CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_ID), + CONSTRAINT TAPE_POOL_TPN_UN UNIQUE(TAPE_POOL_NAME), + CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1')), + CONSTRAINT TAPE_POOL_VO_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID) +); +CREATE TABLE ARCHIVE_ROUTE( + STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_SCI_NN NOT NULL, + COPY_NB NUMERIC(3, 0) CONSTRAINT ARCHIVE_ROUTE_CN_NN NOT NULL, + TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_TPI_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT ARCHIVE_ROUTE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_LUT_NN NOT NULL, + CONSTRAINT ARCHIVE_ROUTE_PK PRIMARY KEY(STORAGE_CLASS_ID, COPY_NB), + CONSTRAINT ARCHIVE_ROUTE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID), + CONSTRAINT ARCHIVE_ROUTE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), + CONSTRAINT ARCHIVE_ROUTE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0), + CONSTRAINT ARCHIVE_ROUTE_SCI_TPI_UN UNIQUE(STORAGE_CLASS_ID, TAPE_POOL_ID) +); +CREATE TABLE MEDIA_TYPE( + MEDIA_TYPE_ID NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_MTI_NN NOT NULL, + MEDIA_TYPE_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_MTN_NN NOT NULL, + CARTRIDGE VARCHAR(100) CONSTRAINT MEDIA_TYPE_C_NN NOT NULL, + CAPACITY_IN_BYTES NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_CIB_NN NOT NULL, + PRIMARY_DENSITY_CODE NUMERIC(3, 0), + SECONDARY_DENSITY_CODE NUMERIC(3, 0), + NB_WRAPS NUMERIC(10, 0), + MIN_LPOS NUMERIC(20, 0), + MAX_LPOS NUMERIC(20, 0), + USER_COMMENT VARCHAR(1000) CONSTRAINT MEDIA_TYPE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_LUT_NN NOT NULL, + CONSTRAINT MEDIA_TYPE_PK PRIMARY KEY(MEDIA_TYPE_ID), + CONSTRAINT MEDIA_TYPE_MTN_UN UNIQUE(MEDIA_TYPE_NAME) +); +CREATE TABLE LOGICAL_LIBRARY( + LOGICAL_LIBRARY_ID NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_LLI_NN NOT NULL, + LOGICAL_LIBRARY_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LLN_NN NOT NULL, + IS_DISABLED CHAR(1) DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT LOGICAL_LIBRARY_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_LUT_NN NOT NULL, + CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_ID), + CONSTRAINT LOGICAL_LIBRARY_LLN_UN UNIQUE(LOGICAL_LIBRARY_NAME), + CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1')) +); +CREATE TABLE TAPE( + VID VARCHAR(100) CONSTRAINT TAPE_V_NN NOT NULL, + MEDIA_TYPE_ID NUMERIC(20, 0) CONSTRAINT TAPE_MTID_NN NOT NULL, + VENDOR VARCHAR(100) CONSTRAINT TAPE_V2_NN NOT NULL, + LOGICAL_LIBRARY_ID NUMERIC(20, 0) CONSTRAINT TAPE_LLI_NN NOT NULL, + TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT TAPE_TPI_NN NOT NULL, + ENCRYPTION_KEY_NAME VARCHAR(100), + DATA_IN_BYTES NUMERIC(20, 0) CONSTRAINT TAPE_DIB_NN NOT NULL, + LAST_FSEQ NUMERIC(20, 0) CONSTRAINT TAPE_LF_NN NOT NULL, + NB_MASTER_FILES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_MASTER_FILES_NN NOT NULL, + MASTER_DATA_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_MASTER_DATA_IN_BYTES_NN NOT NULL, + IS_FULL CHAR(1) CONSTRAINT TAPE_IF_NN NOT NULL, + IS_FROM_CASTOR CHAR(1) CONSTRAINT TAPE_IFC_NN NOT NULL, + DIRTY CHAR(1) DEFAULT '1' CONSTRAINT TAPE_DIRTY_NN NOT NULL, + NB_COPY_NB_1 NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_1_NN NOT NULL, + COPY_NB_1_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_COPY_NB_1_IN_BYTES_NN NOT NULL, + NB_COPY_NB_GT_1 NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_GT_1_NN NOT NULL, + COPY_NB_GT_1_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_COPY_NB_GT_1_IN_BYTES_NN NOT NULL, + LABEL_DRIVE VARCHAR(100), + LABEL_TIME NUMERIC(20, 0) , + LAST_READ_DRIVE VARCHAR(100), + LAST_READ_TIME NUMERIC(20, 0) , + LAST_WRITE_DRIVE VARCHAR(100), + LAST_WRITE_TIME NUMERIC(20, 0) , + READ_MOUNT_COUNT NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL, + WRITE_MOUNT_COUNT NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL, + USER_COMMENT VARCHAR(1000), + TAPE_STATE VARCHAR(100) CONSTRAINT TAPE_TS_NN NOT NULL, + STATE_REASON VARCHAR(1000), + STATE_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_SUT_NN NOT NULL, + STATE_MODIFIED_BY VARCHAR(100) CONSTRAINT TAPE_SMB_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT TAPE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_LUT_NN NOT NULL, + CONSTRAINT TAPE_PK PRIMARY KEY(VID), + CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID), + CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), + CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1')), + CONSTRAINT TAPE_IS_FROM_CASTOR_BOOL_CK CHECK(IS_FROM_CASTOR IN ('0', '1')), + CONSTRAINT TAPE_DIRTY_BOOL_CK CHECK(DIRTY IN ('0','1')), + CONSTRAINT TAPE_STATE_CK CHECK(TAPE_STATE IN ('ACTIVE', 'DISABLED', 'BROKEN')), + CONSTRAINT TAPE_MEDIA_TYPE_FK FOREIGN KEY(MEDIA_TYPE_ID) REFERENCES MEDIA_TYPE(MEDIA_TYPE_ID) +); +CREATE INDEX TAPE_TAPE_POOL_ID_IDX ON TAPE(TAPE_POOL_ID); +CREATE INDEX TAPE_STATE_IDX ON TAPE(TAPE_STATE); +CREATE TABLE MOUNT_POLICY( + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_MPN_NN NOT NULL, + ARCHIVE_PRIORITY NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_AP_NN NOT NULL, + ARCHIVE_MIN_REQUEST_AGE NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_AMRA_NN NOT NULL, + RETRIEVE_PRIORITY NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_RP_NN NOT NULL, + RETRIEVE_MIN_REQUEST_AGE NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_RMRA_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT MOUNT_POLICY_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_LUT_NN NOT NULL, + CONSTRAINT MOUNT_POLICY_PK PRIMARY KEY(MOUNT_POLICY_NAME) +); +CREATE TABLE REQUESTER_MOUNT_RULE( + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_DIN_NN NOT NULL, + REQUESTER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_RN_NN NOT NULL, + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_MPN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_RULE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_RULE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_RULE_LUT_NN NOT NULL, + CONSTRAINT RQSTER_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_NAME), + CONSTRAINT RQSTER_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME) + REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME) +); +CREATE TABLE REQUESTER_GROUP_MOUNT_RULE( + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_DIN_NN NOT NULL, + REQUESTER_GROUP_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_RGN_NN NOT NULL, + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_MPN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_GRP_RULE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_GRP_RULE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_GRP_RULE_LUT_NN NOT NULL, + CONSTRAINT RQSTER_GRP_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_GROUP_NAME), + CONSTRAINT RQSTER_GRP_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME) + REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME) +); +CREATE TABLE ARCHIVE_FILE( + ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_AFI_NN NOT NULL, + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DIN_NN NOT NULL, + DISK_FILE_ID VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DFI_NN NOT NULL, + DISK_FILE_UID NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_DFUID_NN NOT NULL, + DISK_FILE_GID NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_DFGID_NN NOT NULL, + SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL, + CHECKSUM_BLOB BYTEA, + CHECKSUM_ADLER32 NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_CB2_NN NOT NULL, + STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL, + CREATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL, + RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL, + IS_DELETED CHAR(1) DEFAULT '0' CONSTRAINT ARCHIVE_FILE_ID_NN NOT NULL, + COLLOCATION_HINT VARCHAR(100), + CONSTRAINT ARCHIVE_FILE_PK PRIMARY KEY(ARCHIVE_FILE_ID), + CONSTRAINT ARCHIVE_FILE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID), + CONSTRAINT ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID), + CONSTRAINT ARCHIVE_FILE_ID_BOOL_CK CHECK(IS_DELETED IN ('0', '1')) +); +CREATE INDEX ARCHIVE_FILE_DIN_IDX ON ARCHIVE_FILE(DISK_INSTANCE_NAME); +CREATE INDEX ARCHIVE_FILE_DFI_IDX ON ARCHIVE_FILE(DISK_FILE_ID); +CREATE TABLE TAPE_FILE( + VID VARCHAR(100) CONSTRAINT TAPE_FILE_V_NN NOT NULL, + FSEQ NUMERIC(20, 0) CONSTRAINT TAPE_FILE_F_NN NOT NULL, + BLOCK_ID NUMERIC(20, 0) CONSTRAINT TAPE_FILE_BI_NN NOT NULL, + LOGICAL_SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CSIB_NN NOT NULL, + COPY_NB NUMERIC(3, 0) CONSTRAINT TAPE_FILE_CN_NN NOT NULL, + CREATION_TIME NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CT_NN NOT NULL, + ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT TAPE_FILE_AFI_NN NOT NULL, + CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ), + CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID) + REFERENCES TAPE(VID), + CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID) + REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID), + CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID), + CONSTRAINT TAPE_FILE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0) +); +CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID); +CREATE INDEX TAPE_FILE_ARCHIVE_FILE_ID_IDX ON TAPE_FILE(ARCHIVE_FILE_ID); +CREATE TABLE ACTIVITIES_WEIGHTS ( + DISK_INSTANCE_NAME VARCHAR(100), + ACTIVITY VARCHAR(100), + WEIGHT VARCHAR(100), + USER_COMMENT VARCHAR(1000) CONSTRAINT ACTIV_WEIGHTS_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLHN_NN NOT NULL, + CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ACTIV_WEIGHTS_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUHN_NN NOT NULL, + LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ACTIV_WEIGHTS_LUT_NN NOT NULL +); +CREATE TABLE FILE_RECYCLE_LOG( + FILE_RECYCLE_LOG_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_ID_NN NOT NULL, + VID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_VID_NN NOT NULL, + FSEQ NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_FSEQ_NN NOT NULL, + BLOCK_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_BID_NN NOT NULL, + COPY_NB NUMERIC(3, 0) CONSTRAINT FILE_RECYCLE_LOG_COPY_NB_NN NOT NULL, + TAPE_FILE_CREATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_TFCT_NN NOT NULL, + ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_AFI_NN NOT NULL, + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DIN_NN NOT NULL, + DISK_FILE_ID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFI_NN NOT NULL, + DISK_FILE_ID_WHEN_DELETED VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFIWD_NN NOT NULL, + DISK_FILE_UID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_DFU_NN NOT NULL, + DISK_FILE_GID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_DFG_NN NOT NULL, + SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_SIB_NN NOT NULL, + CHECKSUM_BLOB BYTEA, + CHECKSUM_ADLER32 NUMERIC(10, 0) CONSTRAINT FILE_RECYCLE_LOG_CA_NN NOT NULL, + STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_SCI_NN NOT NULL, + ARCHIVE_FILE_CREATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYLE_LOG_CT_NN NOT NULL, + RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_RT_NN NOT NULL, + COLLOCATION_HINT VARCHAR(100), + DISK_FILE_PATH VARCHAR(2000), + REASON_LOG VARCHAR(1000) CONSTRAINT FILE_RECYCLE_LOG_RL_NN NOT NULL, + RECYCLE_LOG_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_RLT_NN NOT NULL, + CONSTRAINT FILE_RECYCLE_LOG_PK PRIMARY KEY(FILE_RECYCLE_LOG_ID), + CONSTRAINT FILE_RECYCLE_LOG_VID_FK FOREIGN KEY(VID) REFERENCES TAPE(VID), + CONSTRAINT FILE_RECYCLE_LOG_SC_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID) +); +CREATE INDEX FILE_RECYCLE_LOG_DFI_IDX ON FILE_RECYCLE_LOG(DISK_FILE_ID); + +CREATE TABLE DRIVE_CONFIG ( + DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_DN_NN NOT NULL, + CATEGORY VARCHAR(100) CONSTRAINT DRIVE_CONFIG_C_NN NOT NULL, + KEY_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_KN_NN NOT NULL, + VALUE VARCHAR(1000) CONSTRAINT DRIVE_CONFIG_V_NN NOT NULL, + SOURCE VARCHAR(100) CONSTRAINT DRIVE_CONFIG_S_NN NOT NULL, + CONSTRAINT DRIVE_CONFIG_DN_PK PRIMARY KEY(KEY_NAME, DRIVE_NAME) +); + +CREATE TABLE TAPE_DRIVE ( + DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DN_NN NOT NULL, + HOST VARCHAR(100) CONSTRAINT DRIVE_STATE_H_NN NOT NULL, + LOGICAL_LIBRARY VARCHAR(100) CONSTRAINT DRIVE_STATE_LL_NN NOT NULL, + SESSION_ID NUMERIC(20, 0), + BYTES_TRANSFERED_IN_SESSION NUMERIC(20, 0), + FILES_TRANSFERED_IN_SESSION NUMERIC(20, 0), + LATEST_BANDWIDTH VARCHAR(100), + SESSION_START_TIME NUMERIC(20, 0), + MOUNT_START_TIME NUMERIC(20, 0), + TRANSFER_START_TIME NUMERIC(20, 0), + UNLOAD_START_TIME NUMERIC(20, 0), + UNMOUNT_START_TIME NUMERIC(20, 0), + DRAINING_START_TIME NUMERIC(20, 0), + DOWN_OR_UP_START_TIME NUMERIC(20, 0), + PROBE_START_TIME NUMERIC(20, 0), + CLEANUP_START_TIME NUMERIC(20, 0), + START_START_TIME NUMERIC(20, 0), + SHUTDOWN_TIME NUMERIC(20, 0), + MOUNT_TYPE NUMERIC(10, 0) CONSTRAINT DRIVE_STATE_MT_NN NOT NULL, + DRIVE_STATUS VARCHAR(100) DEFAULT 'UNKNOWN' CONSTRAINT DRIVE_STATE_DS_NN NOT NULL, + DESIRED_UP CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DU_NN NOT NULL, + DESIRED_FORCE_DOWN CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DFD_NN NOT NULL, + REASON_UP_DOWN VARCHAR(1000), + CURRENT_VID VARCHAR(100), + CTA_VERSION VARCHAR(100), + CURRENT_PRIORITY NUMERIC(20, 0), + CURRENT_ACTIVITY VARCHAR(100), + CURRENT_ACTIVITY_WEIGHT VARCHAR(100), + CURRENT_TAPE_POOL VARCHAR(100), + NEXT_MOUNT_TYPE NUMERIC(10, 0), + NEXT_VID VARCHAR(100), + NEXT_TAPE_POOL VARCHAR(100), + NEXT_PRIORITY NUMERIC(20, 0), + NEXT_ACTIVITY VARCHAR(100), + NEXT_ACTIVITY_WEIGHT VARCHAR(100), + DEV_FILE_NAME VARCHAR(100), + RAW_LIBRARY_SLOT VARCHAR(100), + CURRENT_VO VARCHAR(100), + NEXT_VO VARCHAR(100), + USER_COMMENT VARCHAR(1000), + CREATION_LOG_USER_NAME VARCHAR(100), + CREATION_LOG_HOST_NAME VARCHAR(100), + CREATION_LOG_TIME NUMERIC(20, 0), + LAST_UPDATE_USER_NAME VARCHAR(100), + LAST_UPDATE_HOST_NAME VARCHAR(100), + LAST_UPDATE_TIME NUMERIC(20, 0), + DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DSN_NN NOT NULL, + RESERVED_BYTES NUMERIC(20, 0) CONSTRAINT DRIVE_STATE_RB_NN NOT NULL, + CONSTRAINT DRIVE_STATE_DN_PK PRIMARY KEY(DRIVE_NAME), + CONSTRAINT DRIVE_STATE_DU_BOOL_CK CHECK(DESIRED_UP IN ('0', '1')), + CONSTRAINT DRIVE_STATE_DFD_BOOL_CK CHECK(DESIRED_FORCE_DOWN IN ('0', '1')), + CONSTRAINT DRIVE_STATE_DS_STRING_CK CHECK(DRIVE_STATUS IN ('DOWN', 'UP', 'PROBING', 'STARTING', + 'MOUNTING', 'TRANSFERING', 'UNLOADING', 'UNMOUNTING', 'DRAININGTODISK', 'CLEANINGUP', 'SHUTDOWN', + 'UNKNOWN')) +); +INSERT INTO CTA_CATALOGUE( + SCHEMA_VERSION_MAJOR, + SCHEMA_VERSION_MINOR, + STATUS) +VALUES( + 4, + 2, + 'PRODUCTION'); +ALTER TABLE ARCHIVE_FILE DROP CONSTRAINT + ARCHIVE_FILE_DIN_DFI_UN; +ALTER TABLE ARCHIVE_FILE ADD CONSTRAINT + ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID) DEFERRABLE INITIALLY IMMEDIATE; +ALTER TABLE CTA_CATALOGUE ADD CONSTRAINT + CATALOGUE_STATUS_CONTENT_CK CHECK((NEXT_SCHEMA_VERSION_MAJOR IS NULL AND NEXT_SCHEMA_VERSION_MINOR IS NULL AND STATUS='PRODUCTION') OR (STATUS='UPGRADING')); diff --git a/catalogue/4.2/sqlite_catalogue_schema.sql b/catalogue/4.2/sqlite_catalogue_schema.sql new file mode 100644 index 0000000000000000000000000000000000000000..43ab44ccccf9a52265114bd7e1ea7164d222225b --- /dev/null +++ b/catalogue/4.2/sqlite_catalogue_schema.sql @@ -0,0 +1,406 @@ +CREATE TABLE ARCHIVE_FILE_ID( + ID INTEGER PRIMARY KEY AUTOINCREMENT +); +CREATE TABLE LOGICAL_LIBRARY_ID( + ID INTEGER PRIMARY KEY AUTOINCREMENT +); +CREATE TABLE MEDIA_TYPE_ID( + ID INTEGER PRIMARY KEY AUTOINCREMENT +); +CREATE TABLE STORAGE_CLASS_ID( + ID INTEGER PRIMARY KEY AUTOINCREMENT +); +CREATE TABLE TAPE_POOL_ID( + ID INTEGER PRIMARY KEY AUTOINCREMENT +); +CREATE TABLE VIRTUAL_ORGANIZATION_ID( + ID INTEGER PRIMARY KEY AUTOINCREMENT +); +CREATE TABLE FILE_RECYCLE_LOG_ID( + ID INTEGER PRIMARY KEY AUTOINCREMENT +); +CREATE TABLE CTA_CATALOGUE( + SCHEMA_VERSION_MAJOR INTEGER CONSTRAINT CTA_CATALOGUE_SVM1_NN NOT NULL, + SCHEMA_VERSION_MINOR INTEGER CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL, + NEXT_SCHEMA_VERSION_MAJOR INTEGER, + NEXT_SCHEMA_VERSION_MINOR INTEGER, + STATUS VARCHAR(100), + IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL, + CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1')) +); +CREATE TABLE ADMIN_USER( + ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT ADMIN_USER_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT ADMIN_USER_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT ADMIN_USER_LUT_NN NOT NULL, + CONSTRAINT ADMIN_USER_PK PRIMARY KEY(ADMIN_USER_NAME) +); +CREATE TABLE DISK_SYSTEM( + DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_DSNM_NN NOT NULL, + FILE_REGEXP VARCHAR(100) CONSTRAINT DISK_SYSTEM_FR_NN NOT NULL, + FREE_SPACE_QUERY_URL VARCHAR(1000) CONSTRAINT DISK_SYSTEM_FSQU_NN NOT NULL, + REFRESH_INTERVAL INTEGER CONSTRAINT DISK_SYSTEM_RI_NN NOT NULL, + TARGETED_FREE_SPACE INTEGER CONSTRAINT DISK_SYSTEM_TFS_NN NOT NULL, + SLEEP_TIME INTEGER CONSTRAINT DISK_SYSTEM_ST_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT DISK_SYSTEM_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT DISK_SYSTEM_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT DISK_SYSTEM_LUT_NN NOT NULL, + CONSTRAINT NAME_PK PRIMARY KEY(DISK_SYSTEM_NAME) +); +CREATE TABLE VIRTUAL_ORGANIZATION( + VIRTUAL_ORGANIZATION_ID INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_VOI_NN NOT NULL, + VIRTUAL_ORGANIZATION_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL, + READ_MAX_DRIVES INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL, + WRITE_MAX_DRIVES INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL, + MAX_FILE_SIZE INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_LUT_NN NOT NULL, + CONSTRAINT VIRTUAL_ORGANIZATION_PK PRIMARY KEY(VIRTUAL_ORGANIZATION_ID), + CONSTRAINT VIRTUAL_ORGANIZATION_VON_UN UNIQUE(VIRTUAL_ORGANIZATION_NAME) +); +CREATE TABLE STORAGE_CLASS( + STORAGE_CLASS_ID INTEGER CONSTRAINT STORAGE_CLASS_SCI_NN NOT NULL, + STORAGE_CLASS_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_SCN_NN NOT NULL, + NB_COPIES INTEGER CONSTRAINT STORAGE_CLASS_NC_NN NOT NULL, + VIRTUAL_ORGANIZATION_ID INTEGER CONSTRAINT STORAGE_CLASS_VOI_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT STORAGE_CLASS_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT STORAGE_CLASS_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT STORAGE_CLASS_LUT_NN NOT NULL, + CONSTRAINT STORAGE_CLASS_PK PRIMARY KEY(STORAGE_CLASS_ID), + CONSTRAINT STORAGE_CLASS_SCN_UN UNIQUE(STORAGE_CLASS_NAME), + CONSTRAINT STORAGE_CLASS_VOI_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID) +); +CREATE TABLE TAPE_POOL( + TAPE_POOL_ID INTEGER CONSTRAINT TAPE_POOL_TPI_NN NOT NULL, + TAPE_POOL_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_TPN_NN NOT NULL, + VIRTUAL_ORGANIZATION_ID INTEGER CONSTRAINT TAPE_POOL_VOI_NN NOT NULL, + NB_PARTIAL_TAPES INTEGER CONSTRAINT TAPE_POOL_NPT_NN NOT NULL, + IS_ENCRYPTED CHAR(1) CONSTRAINT TAPE_POOL_IE_NN NOT NULL, + SUPPLY VARCHAR(100), + USER_COMMENT VARCHAR(1000) CONSTRAINT TAPE_POOL_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT TAPE_POOL_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT TAPE_POOL_LUT_NN NOT NULL, + CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_ID), + CONSTRAINT TAPE_POOL_TPN_UN UNIQUE(TAPE_POOL_NAME), + CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1')), + CONSTRAINT TAPE_POOL_VO_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID) +); +CREATE TABLE ARCHIVE_ROUTE( + STORAGE_CLASS_ID INTEGER CONSTRAINT ARCHIVE_ROUTE_SCI_NN NOT NULL, + COPY_NB INTEGER CONSTRAINT ARCHIVE_ROUTE_CN_NN NOT NULL, + TAPE_POOL_ID INTEGER CONSTRAINT ARCHIVE_ROUTE_TPI_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT ARCHIVE_ROUTE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT ARCHIVE_ROUTE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT ARCHIVE_ROUTE_LUT_NN NOT NULL, + CONSTRAINT ARCHIVE_ROUTE_PK PRIMARY KEY(STORAGE_CLASS_ID, COPY_NB), + CONSTRAINT ARCHIVE_ROUTE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID), + CONSTRAINT ARCHIVE_ROUTE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), + CONSTRAINT ARCHIVE_ROUTE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0), + CONSTRAINT ARCHIVE_ROUTE_SCI_TPI_UN UNIQUE(STORAGE_CLASS_ID, TAPE_POOL_ID) +); +CREATE TABLE MEDIA_TYPE( + MEDIA_TYPE_ID INTEGER CONSTRAINT MEDIA_TYPE_MTI_NN NOT NULL, + MEDIA_TYPE_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_MTN_NN NOT NULL, + CARTRIDGE VARCHAR(100) CONSTRAINT MEDIA_TYPE_C_NN NOT NULL, + CAPACITY_IN_BYTES INTEGER CONSTRAINT MEDIA_TYPE_CIB_NN NOT NULL, + PRIMARY_DENSITY_CODE INTEGER, + SECONDARY_DENSITY_CODE INTEGER, + NB_WRAPS INTEGER, + MIN_LPOS INTEGER, + MAX_LPOS INTEGER, + USER_COMMENT VARCHAR(1000) CONSTRAINT MEDIA_TYPE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT MEDIA_TYPE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT MEDIA_TYPE_LUT_NN NOT NULL, + CONSTRAINT MEDIA_TYPE_PK PRIMARY KEY(MEDIA_TYPE_ID), + CONSTRAINT MEDIA_TYPE_MTN_UN UNIQUE(MEDIA_TYPE_NAME) +); +CREATE TABLE LOGICAL_LIBRARY( + LOGICAL_LIBRARY_ID INTEGER CONSTRAINT LOGICAL_LIBRARY_LLI_NN NOT NULL, + LOGICAL_LIBRARY_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LLN_NN NOT NULL, + IS_DISABLED CHAR(1) DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT LOGICAL_LIBRARY_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT LOGICAL_LIBRARY_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT LOGICAL_LIBRARY_LUT_NN NOT NULL, + CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_ID), + CONSTRAINT LOGICAL_LIBRARY_LLN_UN UNIQUE(LOGICAL_LIBRARY_NAME), + CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1')) +); +CREATE TABLE TAPE( + VID VARCHAR(100) CONSTRAINT TAPE_V_NN NOT NULL, + MEDIA_TYPE_ID INTEGER CONSTRAINT TAPE_MTID_NN NOT NULL, + VENDOR VARCHAR(100) CONSTRAINT TAPE_V2_NN NOT NULL, + LOGICAL_LIBRARY_ID INTEGER CONSTRAINT TAPE_LLI_NN NOT NULL, + TAPE_POOL_ID INTEGER CONSTRAINT TAPE_TPI_NN NOT NULL, + ENCRYPTION_KEY_NAME VARCHAR(100), + DATA_IN_BYTES INTEGER CONSTRAINT TAPE_DIB_NN NOT NULL, + LAST_FSEQ INTEGER CONSTRAINT TAPE_LF_NN NOT NULL, + NB_MASTER_FILES INTEGER DEFAULT 0 CONSTRAINT TAPE_NB_MASTER_FILES_NN NOT NULL, + MASTER_DATA_IN_BYTES INTEGER DEFAULT 0 CONSTRAINT TAPE_MASTER_DATA_IN_BYTES_NN NOT NULL, + IS_FULL CHAR(1) CONSTRAINT TAPE_IF_NN NOT NULL, + IS_FROM_CASTOR CHAR(1) CONSTRAINT TAPE_IFC_NN NOT NULL, + DIRTY CHAR(1) DEFAULT '1' CONSTRAINT TAPE_DIRTY_NN NOT NULL, + NB_COPY_NB_1 INTEGER DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_1_NN NOT NULL, + COPY_NB_1_IN_BYTES INTEGER DEFAULT 0 CONSTRAINT TAPE_COPY_NB_1_IN_BYTES_NN NOT NULL, + NB_COPY_NB_GT_1 INTEGER DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_GT_1_NN NOT NULL, + COPY_NB_GT_1_IN_BYTES INTEGER DEFAULT 0 CONSTRAINT TAPE_COPY_NB_GT_1_IN_BYTES_NN NOT NULL, + LABEL_DRIVE VARCHAR(100), + LABEL_TIME INTEGER , + LAST_READ_DRIVE VARCHAR(100), + LAST_READ_TIME INTEGER , + LAST_WRITE_DRIVE VARCHAR(100), + LAST_WRITE_TIME INTEGER , + READ_MOUNT_COUNT INTEGER DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL, + WRITE_MOUNT_COUNT INTEGER DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL, + USER_COMMENT VARCHAR(1000), + TAPE_STATE VARCHAR(100) CONSTRAINT TAPE_TS_NN NOT NULL, + STATE_REASON VARCHAR(1000), + STATE_UPDATE_TIME INTEGER CONSTRAINT TAPE_SUT_NN NOT NULL, + STATE_MODIFIED_BY VARCHAR(100) CONSTRAINT TAPE_SMB_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT TAPE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT TAPE_LUT_NN NOT NULL, + CONSTRAINT TAPE_PK PRIMARY KEY(VID), + CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID), + CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID), + CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1')), + CONSTRAINT TAPE_IS_FROM_CASTOR_BOOL_CK CHECK(IS_FROM_CASTOR IN ('0', '1')), + CONSTRAINT TAPE_DIRTY_BOOL_CK CHECK(DIRTY IN ('0','1')), + CONSTRAINT TAPE_STATE_CK CHECK(TAPE_STATE IN ('ACTIVE', 'DISABLED', 'BROKEN')), + CONSTRAINT TAPE_MEDIA_TYPE_FK FOREIGN KEY(MEDIA_TYPE_ID) REFERENCES MEDIA_TYPE(MEDIA_TYPE_ID) +); +CREATE INDEX TAPE_TAPE_POOL_ID_IDX ON TAPE(TAPE_POOL_ID); +CREATE INDEX TAPE_STATE_IDX ON TAPE(TAPE_STATE); +CREATE TABLE MOUNT_POLICY( + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_MPN_NN NOT NULL, + ARCHIVE_PRIORITY INTEGER CONSTRAINT MOUNT_POLICY_AP_NN NOT NULL, + ARCHIVE_MIN_REQUEST_AGE INTEGER CONSTRAINT MOUNT_POLICY_AMRA_NN NOT NULL, + RETRIEVE_PRIORITY INTEGER CONSTRAINT MOUNT_POLICY_RP_NN NOT NULL, + RETRIEVE_MIN_REQUEST_AGE INTEGER CONSTRAINT MOUNT_POLICY_RMRA_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT MOUNT_POLICY_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT MOUNT_POLICY_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT MOUNT_POLICY_LUT_NN NOT NULL, + CONSTRAINT MOUNT_POLICY_PK PRIMARY KEY(MOUNT_POLICY_NAME) +); +CREATE TABLE REQUESTER_MOUNT_RULE( + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_DIN_NN NOT NULL, + REQUESTER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_RN_NN NOT NULL, + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_MPN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_RULE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT RQSTER_RULE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT RQSTER_RULE_LUT_NN NOT NULL, + CONSTRAINT RQSTER_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_NAME), + CONSTRAINT RQSTER_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME) + REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME) +); +CREATE TABLE REQUESTER_GROUP_MOUNT_RULE( + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_DIN_NN NOT NULL, + REQUESTER_GROUP_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_RGN_NN NOT NULL, + MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_MPN_NN NOT NULL, + USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_GRP_RULE_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT RQSTER_GRP_RULE_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT RQSTER_GRP_RULE_LUT_NN NOT NULL, + CONSTRAINT RQSTER_GRP_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_GROUP_NAME), + CONSTRAINT RQSTER_GRP_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME) + REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME) +); +CREATE TABLE ARCHIVE_FILE( + ARCHIVE_FILE_ID INTEGER CONSTRAINT ARCHIVE_FILE_AFI_NN NOT NULL, + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DIN_NN NOT NULL, + DISK_FILE_ID VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DFI_NN NOT NULL, + DISK_FILE_UID INTEGER CONSTRAINT ARCHIVE_FILE_DFUID_NN NOT NULL, + DISK_FILE_GID INTEGER CONSTRAINT ARCHIVE_FILE_DFGID_NN NOT NULL, + SIZE_IN_BYTES INTEGER CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL, + CHECKSUM_BLOB BLOB(200), + CHECKSUM_ADLER32 INTEGER CONSTRAINT ARCHIVE_FILE_CB2_NN NOT NULL, + STORAGE_CLASS_ID INTEGER CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL, + CREATION_TIME INTEGER CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL, + RECONCILIATION_TIME INTEGER CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL, + IS_DELETED CHAR(1) DEFAULT '0' CONSTRAINT ARCHIVE_FILE_ID_NN NOT NULL, + COLLOCATION_HINT VARCHAR(100), + CONSTRAINT ARCHIVE_FILE_PK PRIMARY KEY(ARCHIVE_FILE_ID), + CONSTRAINT ARCHIVE_FILE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID), + CONSTRAINT ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID), + CONSTRAINT ARCHIVE_FILE_ID_BOOL_CK CHECK(IS_DELETED IN ('0', '1')) +); +CREATE INDEX ARCHIVE_FILE_DIN_IDX ON ARCHIVE_FILE(DISK_INSTANCE_NAME); +CREATE INDEX ARCHIVE_FILE_DFI_IDX ON ARCHIVE_FILE(DISK_FILE_ID); +CREATE TABLE TAPE_FILE( + VID VARCHAR(100) CONSTRAINT TAPE_FILE_V_NN NOT NULL, + FSEQ INTEGER CONSTRAINT TAPE_FILE_F_NN NOT NULL, + BLOCK_ID INTEGER CONSTRAINT TAPE_FILE_BI_NN NOT NULL, + LOGICAL_SIZE_IN_BYTES INTEGER CONSTRAINT TAPE_FILE_CSIB_NN NOT NULL, + COPY_NB INTEGER CONSTRAINT TAPE_FILE_CN_NN NOT NULL, + CREATION_TIME INTEGER CONSTRAINT TAPE_FILE_CT_NN NOT NULL, + ARCHIVE_FILE_ID INTEGER CONSTRAINT TAPE_FILE_AFI_NN NOT NULL, + CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ), + CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID) + REFERENCES TAPE(VID), + CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID) + REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID), + CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID), + CONSTRAINT TAPE_FILE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0) +); +CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID); +CREATE INDEX TAPE_FILE_ARCHIVE_FILE_ID_IDX ON TAPE_FILE(ARCHIVE_FILE_ID); +CREATE TABLE ACTIVITIES_WEIGHTS ( + DISK_INSTANCE_NAME VARCHAR(100), + ACTIVITY VARCHAR(100), + WEIGHT VARCHAR(100), + USER_COMMENT VARCHAR(1000) CONSTRAINT ACTIV_WEIGHTS_UC_NN NOT NULL, + CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLUN_NN NOT NULL, + CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLHN_NN NOT NULL, + CREATION_LOG_TIME INTEGER CONSTRAINT ACTIV_WEIGHTS_CLT_NN NOT NULL, + LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUUN_NN NOT NULL, + LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUHN_NN NOT NULL, + LAST_UPDATE_TIME INTEGER CONSTRAINT ACTIV_WEIGHTS_LUT_NN NOT NULL +); +CREATE TABLE FILE_RECYCLE_LOG( + FILE_RECYCLE_LOG_ID INTEGER CONSTRAINT FILE_RECYCLE_LOG_ID_NN NOT NULL, + VID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_VID_NN NOT NULL, + FSEQ INTEGER CONSTRAINT FILE_RECYCLE_LOG_FSEQ_NN NOT NULL, + BLOCK_ID INTEGER CONSTRAINT FILE_RECYCLE_LOG_BID_NN NOT NULL, + COPY_NB INTEGER CONSTRAINT FILE_RECYCLE_LOG_COPY_NB_NN NOT NULL, + TAPE_FILE_CREATION_TIME INTEGER CONSTRAINT FILE_RECYCLE_LOG_TFCT_NN NOT NULL, + ARCHIVE_FILE_ID INTEGER CONSTRAINT FILE_RECYCLE_LOG_AFI_NN NOT NULL, + DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DIN_NN NOT NULL, + DISK_FILE_ID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFI_NN NOT NULL, + DISK_FILE_ID_WHEN_DELETED VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFIWD_NN NOT NULL, + DISK_FILE_UID INTEGER CONSTRAINT FILE_RECYCLE_LOG_DFU_NN NOT NULL, + DISK_FILE_GID INTEGER CONSTRAINT FILE_RECYCLE_LOG_DFG_NN NOT NULL, + SIZE_IN_BYTES INTEGER CONSTRAINT FILE_RECYCLE_LOG_SIB_NN NOT NULL, + CHECKSUM_BLOB BLOB(200), + CHECKSUM_ADLER32 INTEGER CONSTRAINT FILE_RECYCLE_LOG_CA_NN NOT NULL, + STORAGE_CLASS_ID INTEGER CONSTRAINT FILE_RECYCLE_LOG_SCI_NN NOT NULL, + ARCHIVE_FILE_CREATION_TIME INTEGER CONSTRAINT FILE_RECYLE_LOG_CT_NN NOT NULL, + RECONCILIATION_TIME INTEGER CONSTRAINT FILE_RECYCLE_LOG_RT_NN NOT NULL, + COLLOCATION_HINT VARCHAR(100), + DISK_FILE_PATH VARCHAR(2000), + REASON_LOG VARCHAR(1000) CONSTRAINT FILE_RECYCLE_LOG_RL_NN NOT NULL, + RECYCLE_LOG_TIME INTEGER CONSTRAINT FILE_RECYCLE_LOG_RLT_NN NOT NULL, + CONSTRAINT FILE_RECYCLE_LOG_PK PRIMARY KEY(FILE_RECYCLE_LOG_ID), + CONSTRAINT FILE_RECYCLE_LOG_VID_FK FOREIGN KEY(VID) REFERENCES TAPE(VID), + CONSTRAINT FILE_RECYCLE_LOG_SC_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID) +); +CREATE INDEX FILE_RECYCLE_LOG_DFI_IDX ON FILE_RECYCLE_LOG(DISK_FILE_ID); + +CREATE TABLE DRIVE_CONFIG ( + DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_DN_NN NOT NULL, + CATEGORY VARCHAR(100) CONSTRAINT DRIVE_CONFIG_C_NN NOT NULL, + KEY_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_KN_NN NOT NULL, + VALUE VARCHAR(1000) CONSTRAINT DRIVE_CONFIG_V_NN NOT NULL, + SOURCE VARCHAR(100) CONSTRAINT DRIVE_CONFIG_S_NN NOT NULL, + CONSTRAINT DRIVE_CONFIG_DN_PK PRIMARY KEY(KEY_NAME, DRIVE_NAME) +); + +CREATE TABLE TAPE_DRIVE ( + DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DN_NN NOT NULL, + HOST VARCHAR(100) CONSTRAINT DRIVE_STATE_H_NN NOT NULL, + LOGICAL_LIBRARY VARCHAR(100) CONSTRAINT DRIVE_STATE_LL_NN NOT NULL, + SESSION_ID INTEGER, + BYTES_TRANSFERED_IN_SESSION INTEGER, + FILES_TRANSFERED_IN_SESSION INTEGER, + LATEST_BANDWIDTH VARCHAR(100), + SESSION_START_TIME INTEGER, + MOUNT_START_TIME INTEGER, + TRANSFER_START_TIME INTEGER, + UNLOAD_START_TIME INTEGER, + UNMOUNT_START_TIME INTEGER, + DRAINING_START_TIME INTEGER, + DOWN_OR_UP_START_TIME INTEGER, + PROBE_START_TIME INTEGER, + CLEANUP_START_TIME INTEGER, + START_START_TIME INTEGER, + SHUTDOWN_TIME INTEGER, + MOUNT_TYPE INTEGER CONSTRAINT DRIVE_STATE_MT_NN NOT NULL, + DRIVE_STATUS VARCHAR(100) DEFAULT 'UNKNOWN' CONSTRAINT DRIVE_STATE_DS_NN NOT NULL, + DESIRED_UP CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DU_NN NOT NULL, + DESIRED_FORCE_DOWN CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DFD_NN NOT NULL, + REASON_UP_DOWN VARCHAR(1000), + CURRENT_VID VARCHAR(100), + CTA_VERSION VARCHAR(100), + CURRENT_PRIORITY INTEGER, + CURRENT_ACTIVITY VARCHAR(100), + CURRENT_ACTIVITY_WEIGHT VARCHAR(100), + CURRENT_TAPE_POOL VARCHAR(100), + NEXT_MOUNT_TYPE INTEGER, + NEXT_VID VARCHAR(100), + NEXT_TAPE_POOL VARCHAR(100), + NEXT_PRIORITY INTEGER, + NEXT_ACTIVITY VARCHAR(100), + NEXT_ACTIVITY_WEIGHT VARCHAR(100), + DEV_FILE_NAME VARCHAR(100), + RAW_LIBRARY_SLOT VARCHAR(100), + CURRENT_VO VARCHAR(100), + NEXT_VO VARCHAR(100), + USER_COMMENT VARCHAR(1000), + CREATION_LOG_USER_NAME VARCHAR(100), + CREATION_LOG_HOST_NAME VARCHAR(100), + CREATION_LOG_TIME INTEGER, + LAST_UPDATE_USER_NAME VARCHAR(100), + LAST_UPDATE_HOST_NAME VARCHAR(100), + LAST_UPDATE_TIME INTEGER, + DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DSN_NN NOT NULL, + RESERVED_BYTES INTEGER CONSTRAINT DRIVE_STATE_RB_NN NOT NULL, + CONSTRAINT DRIVE_STATE_DN_PK PRIMARY KEY(DRIVE_NAME), + CONSTRAINT DRIVE_STATE_DU_BOOL_CK CHECK(DESIRED_UP IN ('0', '1')), + CONSTRAINT DRIVE_STATE_DFD_BOOL_CK CHECK(DESIRED_FORCE_DOWN IN ('0', '1')), + CONSTRAINT DRIVE_STATE_DS_STRING_CK CHECK(DRIVE_STATUS IN ('DOWN', 'UP', 'PROBING', 'STARTING', + 'MOUNTING', 'TRANSFERING', 'UNLOADING', 'UNMOUNTING', 'DRAININGTODISK', 'CLEANINGUP', 'SHUTDOWN', + 'UNKNOWN')) +); +INSERT INTO CTA_CATALOGUE( + SCHEMA_VERSION_MAJOR, + SCHEMA_VERSION_MINOR, + STATUS) +VALUES( + 4, + 2, + 'PRODUCTION'); diff --git a/catalogue/AllCatalogueSchema.hpp b/catalogue/AllCatalogueSchema.hpp index 4c56470c0808e81c276cee9cd6c92ed2c666e900..02b9a97212992db8c125f7315b7e264e80c6fe1c 100644 --- a/catalogue/AllCatalogueSchema.hpp +++ b/catalogue/AllCatalogueSchema.hpp @@ -11871,6 +11871,1736 @@ namespace catalogue{ " CATALOGUE_STATUS_CONTENT_CK CHECK((NEXT_SCHEMA_VERSION_MAJOR IS NULL AND NEXT_SCHEMA_VERSION_MINOR IS NULL AND STATUS='PRODUCTION') OR (STATUS='UPGRADING'));" }, } }, + {"4.2", + { + {"oracle", "CREATE SEQUENCE ARCHIVE_FILE_ID_SEQ" + " INCREMENT BY 1" + " START WITH 4294967296" + " NOMAXVALUE" + " MINVALUE 1" + " NOCYCLE" + " CACHE 20" + " NOORDER;" + "CREATE SEQUENCE LOGICAL_LIBRARY_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NOMAXVALUE" + " MINVALUE 1" + " NOCYCLE" + " CACHE 20" + " NOORDER;" + "CREATE SEQUENCE MEDIA_TYPE_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NOMAXVALUE" + " MINVALUE 1" + " NOCYCLE" + " CACHE 20" + " NOORDER;" + "CREATE SEQUENCE STORAGE_CLASS_ID_SEQ" + " INCREMENT BY 1" + " START WITH 10000" + " NOMAXVALUE" + " MINVALUE 1" + " NOCYCLE" + " CACHE 20" + " NOORDER;" + "CREATE SEQUENCE TAPE_POOL_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NOMAXVALUE" + " MINVALUE 1" + " NOCYCLE" + " CACHE 20" + " NOORDER;" + "CREATE SEQUENCE VIRTUAL_ORGANIZATION_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NOMAXVALUE" + " MINVALUE 1" + " NOCYCLE" + " CACHE 20" + " NOORDER;" + "CREATE SEQUENCE FILE_RECYCLE_LOG_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NOMAXVALUE" + " MINVALUE 1" + " NOCYCLE" + " CACHE 20" + " NOORDER;" + "CREATE GLOBAL TEMPORARY TABLE TEMP_TAPE_FILE_INSERTION_BATCH(" + " VID VARCHAR2(100)," + " FSEQ NUMERIC(20, 0) ," + " BLOCK_ID NUMERIC(20, 0) ," + " LOGICAL_SIZE_IN_BYTES NUMERIC(20, 0) ," + " COPY_NB NUMERIC(3, 0) ," + " CREATION_TIME NUMERIC(20, 0) ," + " ARCHIVE_FILE_ID NUMERIC(20, 0)" + ")" + "ON COMMIT DELETE ROWS;" + "CREATE INDEX TEMP_T_F_I_B_AFI_IDX ON TEMP_TAPE_FILE_INSERTION_BATCH(ARCHIVE_FILE_ID);" + "CREATE TABLE CTA_CATALOGUE(" + " SCHEMA_VERSION_MAJOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM1_NN NOT NULL," + " SCHEMA_VERSION_MINOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL," + " NEXT_SCHEMA_VERSION_MAJOR NUMERIC(20, 0)," + " NEXT_SCHEMA_VERSION_MINOR NUMERIC(20, 0)," + " STATUS VARCHAR2(100)," + " IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL," + " CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))" + ");" + "CREATE TABLE ADMIN_USER(" + " ADMIN_USER_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT ADMIN_USER_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ADMIN_USER_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT ADMIN_USER_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ADMIN_USER_LUT_NN NOT NULL," + " CONSTRAINT ADMIN_USER_PK PRIMARY KEY(ADMIN_USER_NAME)" + ");" + "CREATE TABLE DISK_SYSTEM(" + " DISK_SYSTEM_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_DSNM_NN NOT NULL," + " FILE_REGEXP VARCHAR2(100) CONSTRAINT DISK_SYSTEM_FR_NN NOT NULL," + " FREE_SPACE_QUERY_URL VARCHAR2(1000) CONSTRAINT DISK_SYSTEM_FSQU_NN NOT NULL," + " REFRESH_INTERVAL NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_RI_NN NOT NULL," + " TARGETED_FREE_SPACE NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_TFS_NN NOT NULL," + " SLEEP_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_ST_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT DISK_SYSTEM_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT DISK_SYSTEM_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_LUT_NN NOT NULL," + " CONSTRAINT NAME_PK PRIMARY KEY(DISK_SYSTEM_NAME)" + ");" + "CREATE TABLE VIRTUAL_ORGANIZATION(" + " VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_VOI_NN NOT NULL," + " VIRTUAL_ORGANIZATION_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL," + " READ_MAX_DRIVES NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL," + " WRITE_MAX_DRIVES NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL," + " MAX_FILE_SIZE NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_LUT_NN NOT NULL," + " CONSTRAINT VIRTUAL_ORGANIZATION_PK PRIMARY KEY(VIRTUAL_ORGANIZATION_ID)," + " CONSTRAINT VIRTUAL_ORGANIZATION_VON_UN UNIQUE(VIRTUAL_ORGANIZATION_NAME)" + ");" + "CREATE TABLE STORAGE_CLASS(" + " STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_SCI_NN NOT NULL," + " STORAGE_CLASS_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_SCN_NN NOT NULL," + " NB_COPIES NUMERIC(3, 0) CONSTRAINT STORAGE_CLASS_NC_NN NOT NULL," + " VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_VOI_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT STORAGE_CLASS_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT STORAGE_CLASS_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_LUT_NN NOT NULL," + " CONSTRAINT STORAGE_CLASS_PK PRIMARY KEY(STORAGE_CLASS_ID)," + " CONSTRAINT STORAGE_CLASS_SCN_UN UNIQUE(STORAGE_CLASS_NAME)," + " CONSTRAINT STORAGE_CLASS_VOI_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID)" + ");" + "CREATE TABLE TAPE_POOL(" + " TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT TAPE_POOL_TPI_NN NOT NULL," + " TAPE_POOL_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_TPN_NN NOT NULL," + " VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT TAPE_POOL_VOI_NN NOT NULL," + " NB_PARTIAL_TAPES NUMERIC(20, 0) CONSTRAINT TAPE_POOL_NPT_NN NOT NULL," + " IS_ENCRYPTED CHAR(1) CONSTRAINT TAPE_POOL_IE_NN NOT NULL," + " SUPPLY VARCHAR2(100)," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT TAPE_POOL_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT TAPE_POOL_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_POOL_LUT_NN NOT NULL," + " CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_ID)," + " CONSTRAINT TAPE_POOL_TPN_UN UNIQUE(TAPE_POOL_NAME)," + " CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1'))," + " CONSTRAINT TAPE_POOL_VO_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID)" + ");" + "CREATE TABLE ARCHIVE_ROUTE(" + " STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_SCI_NN NOT NULL," + " COPY_NB NUMERIC(3, 0) CONSTRAINT ARCHIVE_ROUTE_CN_NN NOT NULL," + " TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_TPI_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT ARCHIVE_ROUTE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_ROUTE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_ROUTE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_ROUTE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_ROUTE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_LUT_NN NOT NULL," + " CONSTRAINT ARCHIVE_ROUTE_PK PRIMARY KEY(STORAGE_CLASS_ID, COPY_NB)," + " CONSTRAINT ARCHIVE_ROUTE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)," + " CONSTRAINT ARCHIVE_ROUTE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," + " CONSTRAINT ARCHIVE_ROUTE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0)," + " CONSTRAINT ARCHIVE_ROUTE_SCI_TPI_UN UNIQUE(STORAGE_CLASS_ID, TAPE_POOL_ID)" + ");" + "CREATE TABLE MEDIA_TYPE(" + " MEDIA_TYPE_ID NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_MTI_NN NOT NULL," + " MEDIA_TYPE_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_MTN_NN NOT NULL," + " CARTRIDGE VARCHAR2(100) CONSTRAINT MEDIA_TYPE_C_NN NOT NULL," + " CAPACITY_IN_BYTES NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_CIB_NN NOT NULL," + " PRIMARY_DENSITY_CODE NUMERIC(3, 0)," + " SECONDARY_DENSITY_CODE NUMERIC(3, 0)," + " NB_WRAPS NUMERIC(10, 0)," + " MIN_LPOS NUMERIC(20, 0)," + " MAX_LPOS NUMERIC(20, 0)," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT MEDIA_TYPE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT MEDIA_TYPE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_LUT_NN NOT NULL," + " CONSTRAINT MEDIA_TYPE_PK PRIMARY KEY(MEDIA_TYPE_ID)," + " CONSTRAINT MEDIA_TYPE_MTN_UN UNIQUE(MEDIA_TYPE_NAME)" + ");" + "CREATE TABLE LOGICAL_LIBRARY(" + " LOGICAL_LIBRARY_ID NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_LLI_NN NOT NULL," + " LOGICAL_LIBRARY_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_LLN_NN NOT NULL," + " IS_DISABLED CHAR(1) DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT LOGICAL_LIBRARY_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_LUT_NN NOT NULL," + " CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_ID)," + " CONSTRAINT LOGICAL_LIBRARY_LLN_UN UNIQUE(LOGICAL_LIBRARY_NAME)," + " CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1'))" + ");" + "CREATE TABLE TAPE(" + " VID VARCHAR2(100) CONSTRAINT TAPE_V_NN NOT NULL," + " MEDIA_TYPE_ID NUMERIC(20, 0) CONSTRAINT TAPE_MTID_NN NOT NULL," + " VENDOR VARCHAR2(100) CONSTRAINT TAPE_V2_NN NOT NULL," + " LOGICAL_LIBRARY_ID NUMERIC(20, 0) CONSTRAINT TAPE_LLI_NN NOT NULL," + " TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT TAPE_TPI_NN NOT NULL," + " ENCRYPTION_KEY_NAME VARCHAR2(100)," + " DATA_IN_BYTES NUMERIC(20, 0) CONSTRAINT TAPE_DIB_NN NOT NULL," + " LAST_FSEQ NUMERIC(20, 0) CONSTRAINT TAPE_LF_NN NOT NULL," + " NB_MASTER_FILES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_MASTER_FILES_NN NOT NULL," + " MASTER_DATA_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_MASTER_DATA_IN_BYTES_NN NOT NULL," + " IS_FULL CHAR(1) CONSTRAINT TAPE_IF_NN NOT NULL," + " IS_FROM_CASTOR CHAR(1) CONSTRAINT TAPE_IFC_NN NOT NULL," + " DIRTY CHAR(1) DEFAULT '1' CONSTRAINT TAPE_DIRTY_NN NOT NULL," + " NB_COPY_NB_1 NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_1_NN NOT NULL," + " COPY_NB_1_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_COPY_NB_1_IN_BYTES_NN NOT NULL," + " NB_COPY_NB_GT_1 NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_GT_1_NN NOT NULL," + " COPY_NB_GT_1_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_COPY_NB_GT_1_IN_BYTES_NN NOT NULL," + " LABEL_DRIVE VARCHAR2(100)," + " LABEL_TIME NUMERIC(20, 0) ," + " LAST_READ_DRIVE VARCHAR2(100)," + " LAST_READ_TIME NUMERIC(20, 0) ," + " LAST_WRITE_DRIVE VARCHAR2(100)," + " LAST_WRITE_TIME NUMERIC(20, 0) ," + " READ_MOUNT_COUNT NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL," + " WRITE_MOUNT_COUNT NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000)," + " TAPE_STATE VARCHAR2(100) CONSTRAINT TAPE_TS_NN NOT NULL," + " STATE_REASON VARCHAR2(1000)," + " STATE_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_SUT_NN NOT NULL," + " STATE_MODIFIED_BY VARCHAR2(100) CONSTRAINT TAPE_SMB_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT TAPE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT TAPE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT TAPE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_LUT_NN NOT NULL," + " CONSTRAINT TAPE_PK PRIMARY KEY(VID)," + " CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID)," + " CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," + " CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1'))," + " CONSTRAINT TAPE_IS_FROM_CASTOR_BOOL_CK CHECK(IS_FROM_CASTOR IN ('0', '1'))," + " CONSTRAINT TAPE_DIRTY_BOOL_CK CHECK(DIRTY IN ('0','1'))," + " CONSTRAINT TAPE_STATE_CK CHECK(TAPE_STATE IN ('ACTIVE', 'DISABLED', 'BROKEN'))," + " CONSTRAINT TAPE_MEDIA_TYPE_FK FOREIGN KEY(MEDIA_TYPE_ID) REFERENCES MEDIA_TYPE(MEDIA_TYPE_ID)" + ");" + "CREATE INDEX TAPE_TAPE_POOL_ID_IDX ON TAPE(TAPE_POOL_ID);" + "CREATE INDEX TAPE_STATE_IDX ON TAPE(TAPE_STATE);" + "CREATE TABLE MOUNT_POLICY(" + " MOUNT_POLICY_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_MPN_NN NOT NULL," + " ARCHIVE_PRIORITY NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_AP_NN NOT NULL," + " ARCHIVE_MIN_REQUEST_AGE NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_AMRA_NN NOT NULL," + " RETRIEVE_PRIORITY NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_RP_NN NOT NULL," + " RETRIEVE_MIN_REQUEST_AGE NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_RMRA_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT MOUNT_POLICY_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT MOUNT_POLICY_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_LUT_NN NOT NULL," + " CONSTRAINT MOUNT_POLICY_PK PRIMARY KEY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE REQUESTER_MOUNT_RULE(" + " DISK_INSTANCE_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_DIN_NN NOT NULL," + " REQUESTER_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_RN_NN NOT NULL," + " MOUNT_POLICY_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_MPN_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT RQSTER_RULE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_RULE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT RQSTER_RULE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_RULE_LUT_NN NOT NULL," + " CONSTRAINT RQSTER_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_NAME)," + " CONSTRAINT RQSTER_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME)" + " REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE REQUESTER_GROUP_MOUNT_RULE(" + " DISK_INSTANCE_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_DIN_NN NOT NULL," + " REQUESTER_GROUP_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_RGN_NN NOT NULL," + " MOUNT_POLICY_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_MPN_NN NOT NULL," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT RQSTER_GRP_RULE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_GRP_RULE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT RQSTER_GRP_RULE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_GRP_RULE_LUT_NN NOT NULL," + " CONSTRAINT RQSTER_GRP_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_GROUP_NAME)," + " CONSTRAINT RQSTER_GRP_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME)" + " REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE ARCHIVE_FILE(" + " ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_AFI_NN NOT NULL," + " DISK_INSTANCE_NAME VARCHAR2(100) CONSTRAINT ARCHIVE_FILE_DIN_NN NOT NULL," + " DISK_FILE_ID VARCHAR2(100) CONSTRAINT ARCHIVE_FILE_DFI_NN NOT NULL," + " DISK_FILE_UID NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_DFUID_NN NOT NULL," + " DISK_FILE_GID NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_DFGID_NN NOT NULL," + " SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL," + " CHECKSUM_BLOB RAW(200)," + " CHECKSUM_ADLER32 NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_CB2_NN NOT NULL," + " STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL," + " CREATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL," + " RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL," + " IS_DELETED CHAR(1) DEFAULT '0' CONSTRAINT ARCHIVE_FILE_ID_NN NOT NULL," + " COLLOCATION_HINT VARCHAR2(100)," + " CONSTRAINT ARCHIVE_FILE_PK PRIMARY KEY(ARCHIVE_FILE_ID)," + " CONSTRAINT ARCHIVE_FILE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)," + " CONSTRAINT ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID)," + " CONSTRAINT ARCHIVE_FILE_ID_BOOL_CK CHECK(IS_DELETED IN ('0', '1'))" + ");" + "CREATE INDEX ARCHIVE_FILE_DIN_IDX ON ARCHIVE_FILE(DISK_INSTANCE_NAME);" + "CREATE INDEX ARCHIVE_FILE_DFI_IDX ON ARCHIVE_FILE(DISK_FILE_ID);" + "CREATE TABLE TAPE_FILE(" + " VID VARCHAR2(100) CONSTRAINT TAPE_FILE_V_NN NOT NULL," + " FSEQ NUMERIC(20, 0) CONSTRAINT TAPE_FILE_F_NN NOT NULL," + " BLOCK_ID NUMERIC(20, 0) CONSTRAINT TAPE_FILE_BI_NN NOT NULL," + " LOGICAL_SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CSIB_NN NOT NULL," + " COPY_NB NUMERIC(3, 0) CONSTRAINT TAPE_FILE_CN_NN NOT NULL," + " CREATION_TIME NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CT_NN NOT NULL," + " ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT TAPE_FILE_AFI_NN NOT NULL," + " CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ)," + " CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID)" + " REFERENCES TAPE(VID)," + " CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID)" + " REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID)," + " CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID)," + " CONSTRAINT TAPE_FILE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0)" + ");" + "CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID);" + "CREATE INDEX TAPE_FILE_ARCHIVE_FILE_ID_IDX ON TAPE_FILE(ARCHIVE_FILE_ID);" + "CREATE TABLE ACTIVITIES_WEIGHTS (" + " DISK_INSTANCE_NAME VARCHAR2(100)," + " ACTIVITY VARCHAR2(100)," + " WEIGHT VARCHAR2(100)," + " USER_COMMENT VARCHAR2(1000) CONSTRAINT ACTIV_WEIGHTS_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR2(100) CONSTRAINT ACTIV_WEIGHTS_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR2(100) CONSTRAINT ACTIV_WEIGHTS_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ACTIV_WEIGHTS_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR2(100) CONSTRAINT ACTIV_WEIGHTS_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR2(100) CONSTRAINT ACTIV_WEIGHTS_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ACTIV_WEIGHTS_LUT_NN NOT NULL" + ");" + "CREATE TABLE FILE_RECYCLE_LOG(" + " FILE_RECYCLE_LOG_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_ID_NN NOT NULL," + " VID VARCHAR2(100) CONSTRAINT FILE_RECYCLE_LOG_VID_NN NOT NULL," + " FSEQ NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_FSEQ_NN NOT NULL," + " BLOCK_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_BID_NN NOT NULL," + " COPY_NB NUMERIC(3, 0) CONSTRAINT FILE_RECYCLE_LOG_COPY_NB_NN NOT NULL," + " TAPE_FILE_CREATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_TFCT_NN NOT NULL," + " ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_AFI_NN NOT NULL," + " DISK_INSTANCE_NAME VARCHAR2(100) CONSTRAINT FILE_RECYCLE_LOG_DIN_NN NOT NULL," + " DISK_FILE_ID VARCHAR2(100) CONSTRAINT FILE_RECYCLE_LOG_DFI_NN NOT NULL," + " DISK_FILE_ID_WHEN_DELETED VARCHAR2(100) CONSTRAINT FILE_RECYCLE_LOG_DFIWD_NN NOT NULL," + " DISK_FILE_UID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_DFU_NN NOT NULL," + " DISK_FILE_GID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_DFG_NN NOT NULL," + " SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_SIB_NN NOT NULL," + " CHECKSUM_BLOB RAW(200)," + " CHECKSUM_ADLER32 NUMERIC(10, 0) CONSTRAINT FILE_RECYCLE_LOG_CA_NN NOT NULL," + " STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_SCI_NN NOT NULL," + " ARCHIVE_FILE_CREATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYLE_LOG_CT_NN NOT NULL," + " RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_RT_NN NOT NULL," + " COLLOCATION_HINT VARCHAR2(100)," + " DISK_FILE_PATH VARCHAR2(2000)," + " REASON_LOG VARCHAR2(1000) CONSTRAINT FILE_RECYCLE_LOG_RL_NN NOT NULL," + " RECYCLE_LOG_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_RLT_NN NOT NULL," + " CONSTRAINT FILE_RECYCLE_LOG_PK PRIMARY KEY(FILE_RECYCLE_LOG_ID)," + " CONSTRAINT FILE_RECYCLE_LOG_VID_FK FOREIGN KEY(VID) REFERENCES TAPE(VID)," + " CONSTRAINT FILE_RECYCLE_LOG_SC_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)" + ");" + "CREATE INDEX FILE_RECYCLE_LOG_DFI_IDX ON FILE_RECYCLE_LOG(DISK_FILE_ID);" + "" + "CREATE TABLE DRIVE_CONFIG (" + " DRIVE_NAME VARCHAR2(100) CONSTRAINT DRIVE_CONFIG_DN_NN NOT NULL," + " CATEGORY VARCHAR2(100) CONSTRAINT DRIVE_CONFIG_C_NN NOT NULL," + " KEY_NAME VARCHAR2(100) CONSTRAINT DRIVE_CONFIG_KN_NN NOT NULL," + " VALUE VARCHAR2(1000) CONSTRAINT DRIVE_CONFIG_V_NN NOT NULL," + " SOURCE VARCHAR2(100) CONSTRAINT DRIVE_CONFIG_S_NN NOT NULL," + " CONSTRAINT DRIVE_CONFIG_DN_PK PRIMARY KEY(KEY_NAME, DRIVE_NAME)" + ");" + "" + "CREATE TABLE TAPE_DRIVE (" + " DRIVE_NAME VARCHAR2(100) CONSTRAINT DRIVE_STATE_DN_NN NOT NULL," + " HOST VARCHAR2(100) CONSTRAINT DRIVE_STATE_H_NN NOT NULL," + " LOGICAL_LIBRARY VARCHAR2(100) CONSTRAINT DRIVE_STATE_LL_NN NOT NULL," + " SESSION_ID NUMERIC(20, 0)," + " BYTES_TRANSFERED_IN_SESSION NUMERIC(20, 0)," + " FILES_TRANSFERED_IN_SESSION NUMERIC(20, 0)," + " LATEST_BANDWIDTH VARCHAR2(100)," + " SESSION_START_TIME NUMERIC(20, 0)," + " MOUNT_START_TIME NUMERIC(20, 0)," + " TRANSFER_START_TIME NUMERIC(20, 0)," + " UNLOAD_START_TIME NUMERIC(20, 0)," + " UNMOUNT_START_TIME NUMERIC(20, 0)," + " DRAINING_START_TIME NUMERIC(20, 0)," + " DOWN_OR_UP_START_TIME NUMERIC(20, 0)," + " PROBE_START_TIME NUMERIC(20, 0)," + " CLEANUP_START_TIME NUMERIC(20, 0)," + " START_START_TIME NUMERIC(20, 0)," + " SHUTDOWN_TIME NUMERIC(20, 0)," + " MOUNT_TYPE NUMERIC(10, 0) CONSTRAINT DRIVE_STATE_MT_NN NOT NULL," + " DRIVE_STATUS VARCHAR2(100) DEFAULT 'UNKNOWN' CONSTRAINT DRIVE_STATE_DS_NN NOT NULL," + " DESIRED_UP CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DU_NN NOT NULL," + " DESIRED_FORCE_DOWN CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DFD_NN NOT NULL," + " REASON_UP_DOWN VARCHAR2(1000)," + " CURRENT_VID VARCHAR2(100)," + " CTA_VERSION VARCHAR2(100)," + " CURRENT_PRIORITY NUMERIC(20, 0)," + " CURRENT_ACTIVITY VARCHAR2(100)," + " CURRENT_ACTIVITY_WEIGHT VARCHAR2(100)," + " CURRENT_TAPE_POOL VARCHAR2(100)," + " NEXT_MOUNT_TYPE NUMERIC(10, 0)," + " NEXT_VID VARCHAR2(100)," + " NEXT_TAPE_POOL VARCHAR2(100)," + " NEXT_PRIORITY NUMERIC(20, 0)," + " NEXT_ACTIVITY VARCHAR2(100)," + " NEXT_ACTIVITY_WEIGHT VARCHAR2(100)," + " DEV_FILE_NAME VARCHAR2(100)," + " RAW_LIBRARY_SLOT VARCHAR2(100)," + " CURRENT_VO VARCHAR2(100)," + " NEXT_VO VARCHAR2(100)," + " USER_COMMENT VARCHAR2(1000)," + " CREATION_LOG_USER_NAME VARCHAR2(100)," + " CREATION_LOG_HOST_NAME VARCHAR2(100)," + " CREATION_LOG_TIME NUMERIC(20, 0)," + " LAST_UPDATE_USER_NAME VARCHAR2(100)," + " LAST_UPDATE_HOST_NAME VARCHAR2(100)," + " LAST_UPDATE_TIME NUMERIC(20, 0)," + " DISK_SYSTEM_NAME VARCHAR2(100) CONSTRAINT DRIVE_STATE_DSN_NN NOT NULL," + " RESERVED_BYTES NUMERIC(20, 0) CONSTRAINT DRIVE_STATE_RB_NN NOT NULL," + " CONSTRAINT DRIVE_STATE_DN_PK PRIMARY KEY(DRIVE_NAME)," + " CONSTRAINT DRIVE_STATE_DU_BOOL_CK CHECK(DESIRED_UP IN ('0', '1'))," + " CONSTRAINT DRIVE_STATE_DFD_BOOL_CK CHECK(DESIRED_FORCE_DOWN IN ('0', '1'))," + " CONSTRAINT DRIVE_STATE_DS_STRING_CK CHECK(DRIVE_STATUS IN ('DOWN', 'UP', 'PROBING', 'STARTING'," + " 'MOUNTING', 'TRANSFERING', 'UNLOADING', 'UNMOUNTING', 'DRAININGTODISK', 'CLEANINGUP', 'SHUTDOWN'," + " 'UNKNOWN'))" + ");" + "INSERT INTO CTA_CATALOGUE(" + " SCHEMA_VERSION_MAJOR," + " SCHEMA_VERSION_MINOR," + " STATUS)" + "VALUES(" + " 4," + " 2," + " 'PRODUCTION');" + "ALTER TABLE CTA_CATALOGUE ADD CONSTRAINT CATALOGUE_STATUS_CONTENT_CK CHECK((NEXT_SCHEMA_VERSION_MAJOR IS NULL AND NEXT_SCHEMA_VERSION_MINOR IS NULL AND STATUS='PRODUCTION') OR (NEXT_SCHEMA_VERSION_MAJOR IS NOT NULL AND NEXT_SCHEMA_VERSION_MINOR IS NOT NULL AND STATUS='UPGRADING')) INITIALLY DEFERRED;" + "" + "COMMIT;" + }, + {"mysql", "CREATE TABLE ARCHIVE_FILE_ID(" + " ID BIGINT UNSIGNED," + " CONSTRAINT ARCHIVE_FILE_ID_PK PRIMARY KEY(ID)" + ");" + "INSERT INTO ARCHIVE_FILE_ID(ID) VALUES(1);" + "CREATE TABLE LOGICAL_LIBRARY_ID(" + " ID BIGINT UNSIGNED," + " CONSTRAINT LOGICAL_LIBRARY_ID_PK PRIMARY KEY(ID)" + ");" + "INSERT INTO LOGICAL_LIBRARY_ID(ID) VALUES(1);" + "CREATE TABLE MEDIA_TYPE_ID(" + " ID BIGINT UNSIGNED," + " CONSTRAINT MEDIA_TYPE_ID_PK PRIMARY KEY(ID)" + ");" + "INSERT INTO MEDIA_TYPE_ID(ID) VALUES(1);" + "CREATE TABLE STORAGE_CLASS_ID(" + " ID BIGINT UNSIGNED," + " CONSTRAINT STORAGE_CLASS_ID_PK PRIMARY KEY(ID)" + ");" + "INSERT INTO STORAGE_CLASS_ID(ID) VALUES(1);" + "CREATE TABLE TAPE_POOL_ID(" + " ID BIGINT UNSIGNED," + " CONSTRAINT TAPE_POOL_ID_PK PRIMARY KEY(ID)" + ");" + "INSERT INTO TAPE_POOL_ID(ID) VALUES(1);" + "CREATE TABLE VIRTUAL_ORGANIZATION_ID(" + " ID BIGINT UNSIGNED," + " CONSTRAINT VIRTUAL_ORGANIZATION_ID_PK PRIMARY KEY(ID)" + ");" + "INSERT INTO VIRTUAL_ORGANIZATION_ID(ID) VALUES(1);" + "CREATE TABLE FILE_RECYCLE_LOG_ID(" + " ID BIGINT UNSIGNED," + " CONSTRAINT FILE_RECYCLE_LOG_ID PRIMARY KEY(ID)" + ");" + "INSERT INTO FILE_RECYCLE_LOG_ID(ID) VALUES (1);" + "CREATE TABLE CTA_CATALOGUE(" + " SCHEMA_VERSION_MAJOR BIGINT UNSIGNED CONSTRAINT CTA_CATALOGUE_SVM1_NN NOT NULL," + " SCHEMA_VERSION_MINOR BIGINT UNSIGNED CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL," + " NEXT_SCHEMA_VERSION_MAJOR BIGINT UNSIGNED," + " NEXT_SCHEMA_VERSION_MINOR BIGINT UNSIGNED," + " STATUS VARCHAR(100)," + " IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL," + " CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))" + ");" + "CREATE TABLE ADMIN_USER(" + " ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ADMIN_USER_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT ADMIN_USER_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT ADMIN_USER_LUT_NN NOT NULL," + " CONSTRAINT ADMIN_USER_PK PRIMARY KEY(ADMIN_USER_NAME)" + ");" + "CREATE TABLE DISK_SYSTEM(" + " DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_DSNM_NN NOT NULL," + " FILE_REGEXP VARCHAR(100) CONSTRAINT DISK_SYSTEM_FR_NN NOT NULL," + " FREE_SPACE_QUERY_URL VARCHAR(1000) CONSTRAINT DISK_SYSTEM_FSQU_NN NOT NULL," + " REFRESH_INTERVAL BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_RI_NN NOT NULL," + " TARGETED_FREE_SPACE BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_TFS_NN NOT NULL," + " SLEEP_TIME BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_ST_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT DISK_SYSTEM_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT DISK_SYSTEM_LUT_NN NOT NULL," + " CONSTRAINT NAME_PK PRIMARY KEY(DISK_SYSTEM_NAME)" + ");" + "CREATE TABLE VIRTUAL_ORGANIZATION(" + " VIRTUAL_ORGANIZATION_ID BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_VOI_NN NOT NULL," + " VIRTUAL_ORGANIZATION_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL," + " READ_MAX_DRIVES BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL," + " WRITE_MAX_DRIVES BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL," + " MAX_FILE_SIZE BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT VIRTUAL_ORGANIZATION_LUT_NN NOT NULL," + " CONSTRAINT VIRTUAL_ORGANIZATION_PK PRIMARY KEY(VIRTUAL_ORGANIZATION_ID)," + " CONSTRAINT VIRTUAL_ORGANIZATION_VON_UN UNIQUE(VIRTUAL_ORGANIZATION_NAME)" + ");" + "CREATE TABLE STORAGE_CLASS(" + " STORAGE_CLASS_ID BIGINT UNSIGNED CONSTRAINT STORAGE_CLASS_SCI_NN NOT NULL," + " STORAGE_CLASS_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_SCN_NN NOT NULL," + " NB_COPIES TINYINT UNSIGNED CONSTRAINT STORAGE_CLASS_NC_NN NOT NULL," + " VIRTUAL_ORGANIZATION_ID BIGINT UNSIGNED CONSTRAINT STORAGE_CLASS_VOI_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT STORAGE_CLASS_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT STORAGE_CLASS_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT STORAGE_CLASS_LUT_NN NOT NULL," + " CONSTRAINT STORAGE_CLASS_PK PRIMARY KEY(STORAGE_CLASS_ID)," + " CONSTRAINT STORAGE_CLASS_SCN_UN UNIQUE(STORAGE_CLASS_NAME)," + " CONSTRAINT STORAGE_CLASS_VOI_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID)" + ");" + "CREATE TABLE TAPE_POOL(" + " TAPE_POOL_ID BIGINT UNSIGNED CONSTRAINT TAPE_POOL_TPI_NN NOT NULL," + " TAPE_POOL_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_TPN_NN NOT NULL," + " VIRTUAL_ORGANIZATION_ID BIGINT UNSIGNED CONSTRAINT TAPE_POOL_VOI_NN NOT NULL," + " NB_PARTIAL_TAPES BIGINT UNSIGNED CONSTRAINT TAPE_POOL_NPT_NN NOT NULL," + " IS_ENCRYPTED CHAR(1) CONSTRAINT TAPE_POOL_IE_NN NOT NULL," + " SUPPLY VARCHAR(100)," + " USER_COMMENT VARCHAR(1000) CONSTRAINT TAPE_POOL_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT TAPE_POOL_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT TAPE_POOL_LUT_NN NOT NULL," + " CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_ID)," + " CONSTRAINT TAPE_POOL_TPN_UN UNIQUE(TAPE_POOL_NAME)," + " CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1'))," + " CONSTRAINT TAPE_POOL_VO_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID)" + ");" + "CREATE TABLE ARCHIVE_ROUTE(" + " STORAGE_CLASS_ID BIGINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_SCI_NN NOT NULL," + " COPY_NB TINYINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_CN_NN NOT NULL," + " TAPE_POOL_ID BIGINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_TPI_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ARCHIVE_ROUTE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT ARCHIVE_ROUTE_LUT_NN NOT NULL," + " CONSTRAINT ARCHIVE_ROUTE_PK PRIMARY KEY(STORAGE_CLASS_ID, COPY_NB)," + " CONSTRAINT ARCHIVE_ROUTE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)," + " CONSTRAINT ARCHIVE_ROUTE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," + " CONSTRAINT ARCHIVE_ROUTE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0)," + " CONSTRAINT ARCHIVE_ROUTE_SCI_TPI_UN UNIQUE(STORAGE_CLASS_ID, TAPE_POOL_ID)" + ");" + "CREATE TABLE MEDIA_TYPE(" + " MEDIA_TYPE_ID BIGINT UNSIGNED CONSTRAINT MEDIA_TYPE_MTI_NN NOT NULL," + " MEDIA_TYPE_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_MTN_NN NOT NULL," + " CARTRIDGE VARCHAR(100) CONSTRAINT MEDIA_TYPE_C_NN NOT NULL," + " CAPACITY_IN_BYTES BIGINT UNSIGNED CONSTRAINT MEDIA_TYPE_CIB_NN NOT NULL," + " PRIMARY_DENSITY_CODE TINYINT UNSIGNED," + " SECONDARY_DENSITY_CODE TINYINT UNSIGNED," + " NB_WRAPS INT UNSIGNED," + " MIN_LPOS BIGINT UNSIGNED," + " MAX_LPOS BIGINT UNSIGNED," + " USER_COMMENT VARCHAR(1000) CONSTRAINT MEDIA_TYPE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT MEDIA_TYPE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT MEDIA_TYPE_LUT_NN NOT NULL," + " CONSTRAINT MEDIA_TYPE_PK PRIMARY KEY(MEDIA_TYPE_ID)," + " CONSTRAINT MEDIA_TYPE_MTN_UN UNIQUE(MEDIA_TYPE_NAME)" + ");" + "CREATE TABLE LOGICAL_LIBRARY(" + " LOGICAL_LIBRARY_ID BIGINT UNSIGNED CONSTRAINT LOGICAL_LIBRARY_LLI_NN NOT NULL," + " LOGICAL_LIBRARY_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LLN_NN NOT NULL," + " IS_DISABLED CHAR(1) DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT LOGICAL_LIBRARY_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT LOGICAL_LIBRARY_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT LOGICAL_LIBRARY_LUT_NN NOT NULL," + " CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_ID)," + " CONSTRAINT LOGICAL_LIBRARY_LLN_UN UNIQUE(LOGICAL_LIBRARY_NAME)," + " CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1'))" + ");" + "CREATE TABLE TAPE(" + " VID VARCHAR(100) CONSTRAINT TAPE_V_NN NOT NULL," + " MEDIA_TYPE_ID BIGINT UNSIGNED CONSTRAINT TAPE_MTID_NN NOT NULL," + " VENDOR VARCHAR(100) CONSTRAINT TAPE_V2_NN NOT NULL," + " LOGICAL_LIBRARY_ID BIGINT UNSIGNED CONSTRAINT TAPE_LLI_NN NOT NULL," + " TAPE_POOL_ID BIGINT UNSIGNED CONSTRAINT TAPE_TPI_NN NOT NULL," + " ENCRYPTION_KEY_NAME VARCHAR(100)," + " DATA_IN_BYTES BIGINT UNSIGNED CONSTRAINT TAPE_DIB_NN NOT NULL," + " LAST_FSEQ BIGINT UNSIGNED CONSTRAINT TAPE_LF_NN NOT NULL," + " NB_MASTER_FILES BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_NB_MASTER_FILES_NN NOT NULL," + " MASTER_DATA_IN_BYTES BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_MASTER_DATA_IN_BYTES_NN NOT NULL," + " IS_FULL CHAR(1) CONSTRAINT TAPE_IF_NN NOT NULL," + " IS_FROM_CASTOR CHAR(1) CONSTRAINT TAPE_IFC_NN NOT NULL," + " DIRTY CHAR(1) DEFAULT '1' CONSTRAINT TAPE_DIRTY_NN NOT NULL," + " NB_COPY_NB_1 BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_1_NN NOT NULL," + " COPY_NB_1_IN_BYTES BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_COPY_NB_1_IN_BYTES_NN NOT NULL," + " NB_COPY_NB_GT_1 BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_GT_1_NN NOT NULL," + " COPY_NB_GT_1_IN_BYTES BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_COPY_NB_GT_1_IN_BYTES_NN NOT NULL," + " LABEL_DRIVE VARCHAR(100)," + " LABEL_TIME BIGINT UNSIGNED ," + " LAST_READ_DRIVE VARCHAR(100)," + " LAST_READ_TIME BIGINT UNSIGNED ," + " LAST_WRITE_DRIVE VARCHAR(100)," + " LAST_WRITE_TIME BIGINT UNSIGNED ," + " READ_MOUNT_COUNT BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL," + " WRITE_MOUNT_COUNT BIGINT UNSIGNED DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL," + " USER_COMMENT VARCHAR(1000)," + " TAPE_STATE VARCHAR(100) CONSTRAINT TAPE_TS_NN NOT NULL," + " STATE_REASON VARCHAR(1000)," + " STATE_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT TAPE_SUT_NN NOT NULL," + " STATE_MODIFIED_BY VARCHAR(100) CONSTRAINT TAPE_SMB_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT TAPE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT TAPE_LUT_NN NOT NULL," + " CONSTRAINT TAPE_PK PRIMARY KEY(VID)," + " CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID)," + " CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," + " CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1'))," + " CONSTRAINT TAPE_IS_FROM_CASTOR_BOOL_CK CHECK(IS_FROM_CASTOR IN ('0', '1'))," + " CONSTRAINT TAPE_DIRTY_BOOL_CK CHECK(DIRTY IN ('0','1'))," + " CONSTRAINT TAPE_STATE_CK CHECK(TAPE_STATE IN ('ACTIVE', 'DISABLED', 'BROKEN'))," + " CONSTRAINT TAPE_MEDIA_TYPE_FK FOREIGN KEY(MEDIA_TYPE_ID) REFERENCES MEDIA_TYPE(MEDIA_TYPE_ID)" + ");" + "CREATE INDEX TAPE_TAPE_POOL_ID_IDX ON TAPE(TAPE_POOL_ID);" + "CREATE INDEX TAPE_STATE_IDX ON TAPE(TAPE_STATE);" + "CREATE TABLE MOUNT_POLICY(" + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_MPN_NN NOT NULL," + " ARCHIVE_PRIORITY BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_AP_NN NOT NULL," + " ARCHIVE_MIN_REQUEST_AGE BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_AMRA_NN NOT NULL," + " RETRIEVE_PRIORITY BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_RP_NN NOT NULL," + " RETRIEVE_MIN_REQUEST_AGE BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_RMRA_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT MOUNT_POLICY_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT MOUNT_POLICY_LUT_NN NOT NULL," + " CONSTRAINT MOUNT_POLICY_PK PRIMARY KEY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE REQUESTER_MOUNT_RULE(" + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_DIN_NN NOT NULL," + " REQUESTER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_RN_NN NOT NULL," + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_MPN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_RULE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT RQSTER_RULE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT RQSTER_RULE_LUT_NN NOT NULL," + " CONSTRAINT RQSTER_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_NAME)," + " CONSTRAINT RQSTER_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME)" + " REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE REQUESTER_GROUP_MOUNT_RULE(" + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_DIN_NN NOT NULL," + " REQUESTER_GROUP_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_RGN_NN NOT NULL," + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_MPN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_GRP_RULE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT RQSTER_GRP_RULE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT RQSTER_GRP_RULE_LUT_NN NOT NULL," + " CONSTRAINT RQSTER_GRP_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_GROUP_NAME)," + " CONSTRAINT RQSTER_GRP_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME)" + " REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE ARCHIVE_FILE(" + " ARCHIVE_FILE_ID BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_AFI_NN NOT NULL," + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DIN_NN NOT NULL," + " DISK_FILE_ID VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DFI_NN NOT NULL," + " DISK_FILE_UID INT UNSIGNED CONSTRAINT ARCHIVE_FILE_DFUID_NN NOT NULL," + " DISK_FILE_GID INT UNSIGNED CONSTRAINT ARCHIVE_FILE_DFGID_NN NOT NULL," + " SIZE_IN_BYTES BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL," + " CHECKSUM_BLOB VARBINARY(200)," + " CHECKSUM_ADLER32 INT UNSIGNED CONSTRAINT ARCHIVE_FILE_CB2_NN NOT NULL," + " STORAGE_CLASS_ID BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL," + " CREATION_TIME BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL," + " RECONCILIATION_TIME BIGINT UNSIGNED CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL," + " IS_DELETED CHAR(1) DEFAULT '0' CONSTRAINT ARCHIVE_FILE_ID_NN NOT NULL," + " COLLOCATION_HINT VARCHAR(100)," + " CONSTRAINT ARCHIVE_FILE_PK PRIMARY KEY(ARCHIVE_FILE_ID)," + " CONSTRAINT ARCHIVE_FILE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)," + " CONSTRAINT ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID)," + " CONSTRAINT ARCHIVE_FILE_ID_BOOL_CK CHECK(IS_DELETED IN ('0', '1'))" + ");" + "CREATE INDEX ARCHIVE_FILE_DIN_IDX ON ARCHIVE_FILE(DISK_INSTANCE_NAME);" + "CREATE INDEX ARCHIVE_FILE_DFI_IDX ON ARCHIVE_FILE(DISK_FILE_ID);" + "CREATE TABLE TAPE_FILE(" + " VID VARCHAR(100) CONSTRAINT TAPE_FILE_V_NN NOT NULL," + " FSEQ BIGINT UNSIGNED CONSTRAINT TAPE_FILE_F_NN NOT NULL," + " BLOCK_ID BIGINT UNSIGNED CONSTRAINT TAPE_FILE_BI_NN NOT NULL," + " LOGICAL_SIZE_IN_BYTES BIGINT UNSIGNED CONSTRAINT TAPE_FILE_CSIB_NN NOT NULL," + " COPY_NB TINYINT UNSIGNED CONSTRAINT TAPE_FILE_CN_NN NOT NULL," + " CREATION_TIME BIGINT UNSIGNED CONSTRAINT TAPE_FILE_CT_NN NOT NULL," + " ARCHIVE_FILE_ID BIGINT UNSIGNED CONSTRAINT TAPE_FILE_AFI_NN NOT NULL," + " CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ)," + " CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID)" + " REFERENCES TAPE(VID)," + " CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID)" + " REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID)," + " CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID)," + " CONSTRAINT TAPE_FILE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0)" + ");" + "CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID);" + "CREATE INDEX TAPE_FILE_ARCHIVE_FILE_ID_IDX ON TAPE_FILE(ARCHIVE_FILE_ID);" + "CREATE TABLE ACTIVITIES_WEIGHTS (" + " DISK_INSTANCE_NAME VARCHAR(100)," + " ACTIVITY VARCHAR(100)," + " WEIGHT VARCHAR(100)," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ACTIV_WEIGHTS_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLHN_NN NOT NULL," + " CREATION_LOG_TIME BIGINT UNSIGNED CONSTRAINT ACTIV_WEIGHTS_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME BIGINT UNSIGNED CONSTRAINT ACTIV_WEIGHTS_LUT_NN NOT NULL" + ");" + "CREATE TABLE FILE_RECYCLE_LOG(" + " FILE_RECYCLE_LOG_ID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_ID_NN NOT NULL," + " VID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_VID_NN NOT NULL," + " FSEQ BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_FSEQ_NN NOT NULL," + " BLOCK_ID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_BID_NN NOT NULL," + " COPY_NB TINYINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_COPY_NB_NN NOT NULL," + " TAPE_FILE_CREATION_TIME BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_TFCT_NN NOT NULL," + " ARCHIVE_FILE_ID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_AFI_NN NOT NULL," + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DIN_NN NOT NULL," + " DISK_FILE_ID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFI_NN NOT NULL," + " DISK_FILE_ID_WHEN_DELETED VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFIWD_NN NOT NULL," + " DISK_FILE_UID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_DFU_NN NOT NULL," + " DISK_FILE_GID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_DFG_NN NOT NULL," + " SIZE_IN_BYTES BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_SIB_NN NOT NULL," + " CHECKSUM_BLOB VARBINARY(200)," + " CHECKSUM_ADLER32 INT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_CA_NN NOT NULL," + " STORAGE_CLASS_ID BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_SCI_NN NOT NULL," + " ARCHIVE_FILE_CREATION_TIME BIGINT UNSIGNED CONSTRAINT FILE_RECYLE_LOG_CT_NN NOT NULL," + " RECONCILIATION_TIME BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_RT_NN NOT NULL," + " COLLOCATION_HINT VARCHAR(100)," + " DISK_FILE_PATH VARCHAR(2000)," + " REASON_LOG VARCHAR(1000) CONSTRAINT FILE_RECYCLE_LOG_RL_NN NOT NULL," + " RECYCLE_LOG_TIME BIGINT UNSIGNED CONSTRAINT FILE_RECYCLE_LOG_RLT_NN NOT NULL," + " CONSTRAINT FILE_RECYCLE_LOG_PK PRIMARY KEY(FILE_RECYCLE_LOG_ID)," + " CONSTRAINT FILE_RECYCLE_LOG_VID_FK FOREIGN KEY(VID) REFERENCES TAPE(VID)," + " CONSTRAINT FILE_RECYCLE_LOG_SC_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)" + ");" + "CREATE INDEX FILE_RECYCLE_LOG_DFI_IDX ON FILE_RECYCLE_LOG(DISK_FILE_ID);" + "" + "CREATE TABLE DRIVE_CONFIG (" + " DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_DN_NN NOT NULL," + " CATEGORY VARCHAR(100) CONSTRAINT DRIVE_CONFIG_C_NN NOT NULL," + " KEY_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_KN_NN NOT NULL," + " VALUE VARCHAR(1000) CONSTRAINT DRIVE_CONFIG_V_NN NOT NULL," + " SOURCE VARCHAR(100) CONSTRAINT DRIVE_CONFIG_S_NN NOT NULL," + " CONSTRAINT DRIVE_CONFIG_DN_PK PRIMARY KEY(KEY_NAME, DRIVE_NAME)" + ");" + "" + "CREATE TABLE TAPE_DRIVE (" + " DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DN_NN NOT NULL," + " HOST VARCHAR(100) CONSTRAINT DRIVE_STATE_H_NN NOT NULL," + " LOGICAL_LIBRARY VARCHAR(100) CONSTRAINT DRIVE_STATE_LL_NN NOT NULL," + " SESSION_ID BIGINT UNSIGNED," + " BYTES_TRANSFERED_IN_SESSION BIGINT UNSIGNED," + " FILES_TRANSFERED_IN_SESSION BIGINT UNSIGNED," + " LATEST_BANDWIDTH VARCHAR(100)," + " SESSION_START_TIME BIGINT UNSIGNED," + " MOUNT_START_TIME BIGINT UNSIGNED," + " TRANSFER_START_TIME BIGINT UNSIGNED," + " UNLOAD_START_TIME BIGINT UNSIGNED," + " UNMOUNT_START_TIME BIGINT UNSIGNED," + " DRAINING_START_TIME BIGINT UNSIGNED," + " DOWN_OR_UP_START_TIME BIGINT UNSIGNED," + " PROBE_START_TIME BIGINT UNSIGNED," + " CLEANUP_START_TIME BIGINT UNSIGNED," + " START_START_TIME BIGINT UNSIGNED," + " SHUTDOWN_TIME BIGINT UNSIGNED," + " MOUNT_TYPE INT UNSIGNED CONSTRAINT DRIVE_STATE_MT_NN NOT NULL," + " DRIVE_STATUS VARCHAR(100) DEFAULT 'UNKNOWN' CONSTRAINT DRIVE_STATE_DS_NN NOT NULL," + " DESIRED_UP CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DU_NN NOT NULL," + " DESIRED_FORCE_DOWN CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DFD_NN NOT NULL," + " REASON_UP_DOWN VARCHAR(1000)," + " CURRENT_VID VARCHAR(100)," + " CTA_VERSION VARCHAR(100)," + " CURRENT_PRIORITY BIGINT UNSIGNED," + " CURRENT_ACTIVITY VARCHAR(100)," + " CURRENT_ACTIVITY_WEIGHT VARCHAR(100)," + " CURRENT_TAPE_POOL VARCHAR(100)," + " NEXT_MOUNT_TYPE INT UNSIGNED," + " NEXT_VID VARCHAR(100)," + " NEXT_TAPE_POOL VARCHAR(100)," + " NEXT_PRIORITY BIGINT UNSIGNED," + " NEXT_ACTIVITY VARCHAR(100)," + " NEXT_ACTIVITY_WEIGHT VARCHAR(100)," + " DEV_FILE_NAME VARCHAR(100)," + " RAW_LIBRARY_SLOT VARCHAR(100)," + " CURRENT_VO VARCHAR(100)," + " NEXT_VO VARCHAR(100)," + " USER_COMMENT VARCHAR(1000)," + " CREATION_LOG_USER_NAME VARCHAR(100)," + " CREATION_LOG_HOST_NAME VARCHAR(100)," + " CREATION_LOG_TIME BIGINT UNSIGNED," + " LAST_UPDATE_USER_NAME VARCHAR(100)," + " LAST_UPDATE_HOST_NAME VARCHAR(100)," + " LAST_UPDATE_TIME BIGINT UNSIGNED," + " DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DSN_NN NOT NULL," + " RESERVED_BYTES BIGINT UNSIGNED CONSTRAINT DRIVE_STATE_RB_NN NOT NULL," + " CONSTRAINT DRIVE_STATE_DN_PK PRIMARY KEY(DRIVE_NAME)," + " CONSTRAINT DRIVE_STATE_DU_BOOL_CK CHECK(DESIRED_UP IN ('0', '1'))," + " CONSTRAINT DRIVE_STATE_DFD_BOOL_CK CHECK(DESIRED_FORCE_DOWN IN ('0', '1'))," + " CONSTRAINT DRIVE_STATE_DS_STRING_CK CHECK(DRIVE_STATUS IN ('DOWN', 'UP', 'PROBING', 'STARTING'," + " 'MOUNTING', 'TRANSFERING', 'UNLOADING', 'UNMOUNTING', 'DRAININGTODISK', 'CLEANINGUP', 'SHUTDOWN'," + " 'UNKNOWN'))" + ");" + "INSERT INTO CTA_CATALOGUE(" + " SCHEMA_VERSION_MAJOR," + " SCHEMA_VERSION_MINOR," + " STATUS)" + "VALUES(" + " 4," + " 2," + " 'PRODUCTION');" + "ALTER TABLE CTA_CATALOGUE ADD CONSTRAINT" + " CATALOGUE_STATUS_CONTENT_CK CHECK((NEXT_SCHEMA_VERSION_MAJOR IS NULL AND NEXT_SCHEMA_VERSION_MINOR IS NULL AND STATUS='PRODUCTION') OR (STATUS='UPGRADING'));" + }, + {"sqlite", "CREATE TABLE ARCHIVE_FILE_ID(" + " ID INTEGER PRIMARY KEY AUTOINCREMENT" + ");" + "CREATE TABLE LOGICAL_LIBRARY_ID(" + " ID INTEGER PRIMARY KEY AUTOINCREMENT" + ");" + "CREATE TABLE MEDIA_TYPE_ID(" + " ID INTEGER PRIMARY KEY AUTOINCREMENT" + ");" + "CREATE TABLE STORAGE_CLASS_ID(" + " ID INTEGER PRIMARY KEY AUTOINCREMENT" + ");" + "CREATE TABLE TAPE_POOL_ID(" + " ID INTEGER PRIMARY KEY AUTOINCREMENT" + ");" + "CREATE TABLE VIRTUAL_ORGANIZATION_ID(" + " ID INTEGER PRIMARY KEY AUTOINCREMENT" + ");" + "CREATE TABLE FILE_RECYCLE_LOG_ID(" + " ID INTEGER PRIMARY KEY AUTOINCREMENT" + ");" + "CREATE TABLE CTA_CATALOGUE(" + " SCHEMA_VERSION_MAJOR INTEGER CONSTRAINT CTA_CATALOGUE_SVM1_NN NOT NULL," + " SCHEMA_VERSION_MINOR INTEGER CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL," + " NEXT_SCHEMA_VERSION_MAJOR INTEGER," + " NEXT_SCHEMA_VERSION_MINOR INTEGER," + " STATUS VARCHAR(100)," + " IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL," + " CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))" + ");" + "CREATE TABLE ADMIN_USER(" + " ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ADMIN_USER_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT ADMIN_USER_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT ADMIN_USER_LUT_NN NOT NULL," + " CONSTRAINT ADMIN_USER_PK PRIMARY KEY(ADMIN_USER_NAME)" + ");" + "CREATE TABLE DISK_SYSTEM(" + " DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_DSNM_NN NOT NULL," + " FILE_REGEXP VARCHAR(100) CONSTRAINT DISK_SYSTEM_FR_NN NOT NULL," + " FREE_SPACE_QUERY_URL VARCHAR(1000) CONSTRAINT DISK_SYSTEM_FSQU_NN NOT NULL," + " REFRESH_INTERVAL INTEGER CONSTRAINT DISK_SYSTEM_RI_NN NOT NULL," + " TARGETED_FREE_SPACE INTEGER CONSTRAINT DISK_SYSTEM_TFS_NN NOT NULL," + " SLEEP_TIME INTEGER CONSTRAINT DISK_SYSTEM_ST_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT DISK_SYSTEM_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT DISK_SYSTEM_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT DISK_SYSTEM_LUT_NN NOT NULL," + " CONSTRAINT NAME_PK PRIMARY KEY(DISK_SYSTEM_NAME)" + ");" + "CREATE TABLE VIRTUAL_ORGANIZATION(" + " VIRTUAL_ORGANIZATION_ID INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_VOI_NN NOT NULL," + " VIRTUAL_ORGANIZATION_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL," + " READ_MAX_DRIVES INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL," + " WRITE_MAX_DRIVES INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL," + " MAX_FILE_SIZE INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT VIRTUAL_ORGANIZATION_LUT_NN NOT NULL," + " CONSTRAINT VIRTUAL_ORGANIZATION_PK PRIMARY KEY(VIRTUAL_ORGANIZATION_ID)," + " CONSTRAINT VIRTUAL_ORGANIZATION_VON_UN UNIQUE(VIRTUAL_ORGANIZATION_NAME)" + ");" + "CREATE TABLE STORAGE_CLASS(" + " STORAGE_CLASS_ID INTEGER CONSTRAINT STORAGE_CLASS_SCI_NN NOT NULL," + " STORAGE_CLASS_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_SCN_NN NOT NULL," + " NB_COPIES INTEGER CONSTRAINT STORAGE_CLASS_NC_NN NOT NULL," + " VIRTUAL_ORGANIZATION_ID INTEGER CONSTRAINT STORAGE_CLASS_VOI_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT STORAGE_CLASS_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT STORAGE_CLASS_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT STORAGE_CLASS_LUT_NN NOT NULL," + " CONSTRAINT STORAGE_CLASS_PK PRIMARY KEY(STORAGE_CLASS_ID)," + " CONSTRAINT STORAGE_CLASS_SCN_UN UNIQUE(STORAGE_CLASS_NAME)," + " CONSTRAINT STORAGE_CLASS_VOI_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID)" + ");" + "CREATE TABLE TAPE_POOL(" + " TAPE_POOL_ID INTEGER CONSTRAINT TAPE_POOL_TPI_NN NOT NULL," + " TAPE_POOL_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_TPN_NN NOT NULL," + " VIRTUAL_ORGANIZATION_ID INTEGER CONSTRAINT TAPE_POOL_VOI_NN NOT NULL," + " NB_PARTIAL_TAPES INTEGER CONSTRAINT TAPE_POOL_NPT_NN NOT NULL," + " IS_ENCRYPTED CHAR(1) CONSTRAINT TAPE_POOL_IE_NN NOT NULL," + " SUPPLY VARCHAR(100)," + " USER_COMMENT VARCHAR(1000) CONSTRAINT TAPE_POOL_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT TAPE_POOL_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT TAPE_POOL_LUT_NN NOT NULL," + " CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_ID)," + " CONSTRAINT TAPE_POOL_TPN_UN UNIQUE(TAPE_POOL_NAME)," + " CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1'))," + " CONSTRAINT TAPE_POOL_VO_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID)" + ");" + "CREATE TABLE ARCHIVE_ROUTE(" + " STORAGE_CLASS_ID INTEGER CONSTRAINT ARCHIVE_ROUTE_SCI_NN NOT NULL," + " COPY_NB INTEGER CONSTRAINT ARCHIVE_ROUTE_CN_NN NOT NULL," + " TAPE_POOL_ID INTEGER CONSTRAINT ARCHIVE_ROUTE_TPI_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ARCHIVE_ROUTE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT ARCHIVE_ROUTE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT ARCHIVE_ROUTE_LUT_NN NOT NULL," + " CONSTRAINT ARCHIVE_ROUTE_PK PRIMARY KEY(STORAGE_CLASS_ID, COPY_NB)," + " CONSTRAINT ARCHIVE_ROUTE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)," + " CONSTRAINT ARCHIVE_ROUTE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," + " CONSTRAINT ARCHIVE_ROUTE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0)," + " CONSTRAINT ARCHIVE_ROUTE_SCI_TPI_UN UNIQUE(STORAGE_CLASS_ID, TAPE_POOL_ID)" + ");" + "CREATE TABLE MEDIA_TYPE(" + " MEDIA_TYPE_ID INTEGER CONSTRAINT MEDIA_TYPE_MTI_NN NOT NULL," + " MEDIA_TYPE_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_MTN_NN NOT NULL," + " CARTRIDGE VARCHAR(100) CONSTRAINT MEDIA_TYPE_C_NN NOT NULL," + " CAPACITY_IN_BYTES INTEGER CONSTRAINT MEDIA_TYPE_CIB_NN NOT NULL," + " PRIMARY_DENSITY_CODE INTEGER," + " SECONDARY_DENSITY_CODE INTEGER," + " NB_WRAPS INTEGER," + " MIN_LPOS INTEGER," + " MAX_LPOS INTEGER," + " USER_COMMENT VARCHAR(1000) CONSTRAINT MEDIA_TYPE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT MEDIA_TYPE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT MEDIA_TYPE_LUT_NN NOT NULL," + " CONSTRAINT MEDIA_TYPE_PK PRIMARY KEY(MEDIA_TYPE_ID)," + " CONSTRAINT MEDIA_TYPE_MTN_UN UNIQUE(MEDIA_TYPE_NAME)" + ");" + "CREATE TABLE LOGICAL_LIBRARY(" + " LOGICAL_LIBRARY_ID INTEGER CONSTRAINT LOGICAL_LIBRARY_LLI_NN NOT NULL," + " LOGICAL_LIBRARY_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LLN_NN NOT NULL," + " IS_DISABLED CHAR(1) DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT LOGICAL_LIBRARY_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT LOGICAL_LIBRARY_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT LOGICAL_LIBRARY_LUT_NN NOT NULL," + " CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_ID)," + " CONSTRAINT LOGICAL_LIBRARY_LLN_UN UNIQUE(LOGICAL_LIBRARY_NAME)," + " CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1'))" + ");" + "CREATE TABLE TAPE(" + " VID VARCHAR(100) CONSTRAINT TAPE_V_NN NOT NULL," + " MEDIA_TYPE_ID INTEGER CONSTRAINT TAPE_MTID_NN NOT NULL," + " VENDOR VARCHAR(100) CONSTRAINT TAPE_V2_NN NOT NULL," + " LOGICAL_LIBRARY_ID INTEGER CONSTRAINT TAPE_LLI_NN NOT NULL," + " TAPE_POOL_ID INTEGER CONSTRAINT TAPE_TPI_NN NOT NULL," + " ENCRYPTION_KEY_NAME VARCHAR(100)," + " DATA_IN_BYTES INTEGER CONSTRAINT TAPE_DIB_NN NOT NULL," + " LAST_FSEQ INTEGER CONSTRAINT TAPE_LF_NN NOT NULL," + " NB_MASTER_FILES INTEGER DEFAULT 0 CONSTRAINT TAPE_NB_MASTER_FILES_NN NOT NULL," + " MASTER_DATA_IN_BYTES INTEGER DEFAULT 0 CONSTRAINT TAPE_MASTER_DATA_IN_BYTES_NN NOT NULL," + " IS_FULL CHAR(1) CONSTRAINT TAPE_IF_NN NOT NULL," + " IS_FROM_CASTOR CHAR(1) CONSTRAINT TAPE_IFC_NN NOT NULL," + " DIRTY CHAR(1) DEFAULT '1' CONSTRAINT TAPE_DIRTY_NN NOT NULL," + " NB_COPY_NB_1 INTEGER DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_1_NN NOT NULL," + " COPY_NB_1_IN_BYTES INTEGER DEFAULT 0 CONSTRAINT TAPE_COPY_NB_1_IN_BYTES_NN NOT NULL," + " NB_COPY_NB_GT_1 INTEGER DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_GT_1_NN NOT NULL," + " COPY_NB_GT_1_IN_BYTES INTEGER DEFAULT 0 CONSTRAINT TAPE_COPY_NB_GT_1_IN_BYTES_NN NOT NULL," + " LABEL_DRIVE VARCHAR(100)," + " LABEL_TIME INTEGER ," + " LAST_READ_DRIVE VARCHAR(100)," + " LAST_READ_TIME INTEGER ," + " LAST_WRITE_DRIVE VARCHAR(100)," + " LAST_WRITE_TIME INTEGER ," + " READ_MOUNT_COUNT INTEGER DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL," + " WRITE_MOUNT_COUNT INTEGER DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL," + " USER_COMMENT VARCHAR(1000)," + " TAPE_STATE VARCHAR(100) CONSTRAINT TAPE_TS_NN NOT NULL," + " STATE_REASON VARCHAR(1000)," + " STATE_UPDATE_TIME INTEGER CONSTRAINT TAPE_SUT_NN NOT NULL," + " STATE_MODIFIED_BY VARCHAR(100) CONSTRAINT TAPE_SMB_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT TAPE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT TAPE_LUT_NN NOT NULL," + " CONSTRAINT TAPE_PK PRIMARY KEY(VID)," + " CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID)," + " CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," + " CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1'))," + " CONSTRAINT TAPE_IS_FROM_CASTOR_BOOL_CK CHECK(IS_FROM_CASTOR IN ('0', '1'))," + " CONSTRAINT TAPE_DIRTY_BOOL_CK CHECK(DIRTY IN ('0','1'))," + " CONSTRAINT TAPE_STATE_CK CHECK(TAPE_STATE IN ('ACTIVE', 'DISABLED', 'BROKEN'))," + " CONSTRAINT TAPE_MEDIA_TYPE_FK FOREIGN KEY(MEDIA_TYPE_ID) REFERENCES MEDIA_TYPE(MEDIA_TYPE_ID)" + ");" + "CREATE INDEX TAPE_TAPE_POOL_ID_IDX ON TAPE(TAPE_POOL_ID);" + "CREATE INDEX TAPE_STATE_IDX ON TAPE(TAPE_STATE);" + "CREATE TABLE MOUNT_POLICY(" + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_MPN_NN NOT NULL," + " ARCHIVE_PRIORITY INTEGER CONSTRAINT MOUNT_POLICY_AP_NN NOT NULL," + " ARCHIVE_MIN_REQUEST_AGE INTEGER CONSTRAINT MOUNT_POLICY_AMRA_NN NOT NULL," + " RETRIEVE_PRIORITY INTEGER CONSTRAINT MOUNT_POLICY_RP_NN NOT NULL," + " RETRIEVE_MIN_REQUEST_AGE INTEGER CONSTRAINT MOUNT_POLICY_RMRA_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT MOUNT_POLICY_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT MOUNT_POLICY_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT MOUNT_POLICY_LUT_NN NOT NULL," + " CONSTRAINT MOUNT_POLICY_PK PRIMARY KEY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE REQUESTER_MOUNT_RULE(" + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_DIN_NN NOT NULL," + " REQUESTER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_RN_NN NOT NULL," + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_MPN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_RULE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT RQSTER_RULE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT RQSTER_RULE_LUT_NN NOT NULL," + " CONSTRAINT RQSTER_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_NAME)," + " CONSTRAINT RQSTER_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME)" + " REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE REQUESTER_GROUP_MOUNT_RULE(" + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_DIN_NN NOT NULL," + " REQUESTER_GROUP_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_RGN_NN NOT NULL," + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_MPN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_GRP_RULE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT RQSTER_GRP_RULE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT RQSTER_GRP_RULE_LUT_NN NOT NULL," + " CONSTRAINT RQSTER_GRP_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_GROUP_NAME)," + " CONSTRAINT RQSTER_GRP_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME)" + " REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE ARCHIVE_FILE(" + " ARCHIVE_FILE_ID INTEGER CONSTRAINT ARCHIVE_FILE_AFI_NN NOT NULL," + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DIN_NN NOT NULL," + " DISK_FILE_ID VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DFI_NN NOT NULL," + " DISK_FILE_UID INTEGER CONSTRAINT ARCHIVE_FILE_DFUID_NN NOT NULL," + " DISK_FILE_GID INTEGER CONSTRAINT ARCHIVE_FILE_DFGID_NN NOT NULL," + " SIZE_IN_BYTES INTEGER CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL," + " CHECKSUM_BLOB BLOB(200)," + " CHECKSUM_ADLER32 INTEGER CONSTRAINT ARCHIVE_FILE_CB2_NN NOT NULL," + " STORAGE_CLASS_ID INTEGER CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL," + " CREATION_TIME INTEGER CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL," + " RECONCILIATION_TIME INTEGER CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL," + " IS_DELETED CHAR(1) DEFAULT '0' CONSTRAINT ARCHIVE_FILE_ID_NN NOT NULL," + " COLLOCATION_HINT VARCHAR(100)," + " CONSTRAINT ARCHIVE_FILE_PK PRIMARY KEY(ARCHIVE_FILE_ID)," + " CONSTRAINT ARCHIVE_FILE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)," + " CONSTRAINT ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID)," + " CONSTRAINT ARCHIVE_FILE_ID_BOOL_CK CHECK(IS_DELETED IN ('0', '1'))" + ");" + "CREATE INDEX ARCHIVE_FILE_DIN_IDX ON ARCHIVE_FILE(DISK_INSTANCE_NAME);" + "CREATE INDEX ARCHIVE_FILE_DFI_IDX ON ARCHIVE_FILE(DISK_FILE_ID);" + "CREATE TABLE TAPE_FILE(" + " VID VARCHAR(100) CONSTRAINT TAPE_FILE_V_NN NOT NULL," + " FSEQ INTEGER CONSTRAINT TAPE_FILE_F_NN NOT NULL," + " BLOCK_ID INTEGER CONSTRAINT TAPE_FILE_BI_NN NOT NULL," + " LOGICAL_SIZE_IN_BYTES INTEGER CONSTRAINT TAPE_FILE_CSIB_NN NOT NULL," + " COPY_NB INTEGER CONSTRAINT TAPE_FILE_CN_NN NOT NULL," + " CREATION_TIME INTEGER CONSTRAINT TAPE_FILE_CT_NN NOT NULL," + " ARCHIVE_FILE_ID INTEGER CONSTRAINT TAPE_FILE_AFI_NN NOT NULL," + " CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ)," + " CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID)" + " REFERENCES TAPE(VID)," + " CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID)" + " REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID)," + " CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID)," + " CONSTRAINT TAPE_FILE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0)" + ");" + "CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID);" + "CREATE INDEX TAPE_FILE_ARCHIVE_FILE_ID_IDX ON TAPE_FILE(ARCHIVE_FILE_ID);" + "CREATE TABLE ACTIVITIES_WEIGHTS (" + " DISK_INSTANCE_NAME VARCHAR(100)," + " ACTIVITY VARCHAR(100)," + " WEIGHT VARCHAR(100)," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ACTIV_WEIGHTS_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLHN_NN NOT NULL," + " CREATION_LOG_TIME INTEGER CONSTRAINT ACTIV_WEIGHTS_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME INTEGER CONSTRAINT ACTIV_WEIGHTS_LUT_NN NOT NULL" + ");" + "CREATE TABLE FILE_RECYCLE_LOG(" + " FILE_RECYCLE_LOG_ID INTEGER CONSTRAINT FILE_RECYCLE_LOG_ID_NN NOT NULL," + " VID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_VID_NN NOT NULL," + " FSEQ INTEGER CONSTRAINT FILE_RECYCLE_LOG_FSEQ_NN NOT NULL," + " BLOCK_ID INTEGER CONSTRAINT FILE_RECYCLE_LOG_BID_NN NOT NULL," + " COPY_NB INTEGER CONSTRAINT FILE_RECYCLE_LOG_COPY_NB_NN NOT NULL," + " TAPE_FILE_CREATION_TIME INTEGER CONSTRAINT FILE_RECYCLE_LOG_TFCT_NN NOT NULL," + " ARCHIVE_FILE_ID INTEGER CONSTRAINT FILE_RECYCLE_LOG_AFI_NN NOT NULL," + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DIN_NN NOT NULL," + " DISK_FILE_ID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFI_NN NOT NULL," + " DISK_FILE_ID_WHEN_DELETED VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFIWD_NN NOT NULL," + " DISK_FILE_UID INTEGER CONSTRAINT FILE_RECYCLE_LOG_DFU_NN NOT NULL," + " DISK_FILE_GID INTEGER CONSTRAINT FILE_RECYCLE_LOG_DFG_NN NOT NULL," + " SIZE_IN_BYTES INTEGER CONSTRAINT FILE_RECYCLE_LOG_SIB_NN NOT NULL," + " CHECKSUM_BLOB BLOB(200)," + " CHECKSUM_ADLER32 INTEGER CONSTRAINT FILE_RECYCLE_LOG_CA_NN NOT NULL," + " STORAGE_CLASS_ID INTEGER CONSTRAINT FILE_RECYCLE_LOG_SCI_NN NOT NULL," + " ARCHIVE_FILE_CREATION_TIME INTEGER CONSTRAINT FILE_RECYLE_LOG_CT_NN NOT NULL," + " RECONCILIATION_TIME INTEGER CONSTRAINT FILE_RECYCLE_LOG_RT_NN NOT NULL," + " COLLOCATION_HINT VARCHAR(100)," + " DISK_FILE_PATH VARCHAR(2000)," + " REASON_LOG VARCHAR(1000) CONSTRAINT FILE_RECYCLE_LOG_RL_NN NOT NULL," + " RECYCLE_LOG_TIME INTEGER CONSTRAINT FILE_RECYCLE_LOG_RLT_NN NOT NULL," + " CONSTRAINT FILE_RECYCLE_LOG_PK PRIMARY KEY(FILE_RECYCLE_LOG_ID)," + " CONSTRAINT FILE_RECYCLE_LOG_VID_FK FOREIGN KEY(VID) REFERENCES TAPE(VID)," + " CONSTRAINT FILE_RECYCLE_LOG_SC_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)" + ");" + "CREATE INDEX FILE_RECYCLE_LOG_DFI_IDX ON FILE_RECYCLE_LOG(DISK_FILE_ID);" + "" + "CREATE TABLE DRIVE_CONFIG (" + " DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_DN_NN NOT NULL," + " CATEGORY VARCHAR(100) CONSTRAINT DRIVE_CONFIG_C_NN NOT NULL," + " KEY_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_KN_NN NOT NULL," + " VALUE VARCHAR(1000) CONSTRAINT DRIVE_CONFIG_V_NN NOT NULL," + " SOURCE VARCHAR(100) CONSTRAINT DRIVE_CONFIG_S_NN NOT NULL," + " CONSTRAINT DRIVE_CONFIG_DN_PK PRIMARY KEY(KEY_NAME, DRIVE_NAME)" + ");" + "" + "CREATE TABLE TAPE_DRIVE (" + " DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DN_NN NOT NULL," + " HOST VARCHAR(100) CONSTRAINT DRIVE_STATE_H_NN NOT NULL," + " LOGICAL_LIBRARY VARCHAR(100) CONSTRAINT DRIVE_STATE_LL_NN NOT NULL," + " SESSION_ID INTEGER," + " BYTES_TRANSFERED_IN_SESSION INTEGER," + " FILES_TRANSFERED_IN_SESSION INTEGER," + " LATEST_BANDWIDTH VARCHAR(100)," + " SESSION_START_TIME INTEGER," + " MOUNT_START_TIME INTEGER," + " TRANSFER_START_TIME INTEGER," + " UNLOAD_START_TIME INTEGER," + " UNMOUNT_START_TIME INTEGER," + " DRAINING_START_TIME INTEGER," + " DOWN_OR_UP_START_TIME INTEGER," + " PROBE_START_TIME INTEGER," + " CLEANUP_START_TIME INTEGER," + " START_START_TIME INTEGER," + " SHUTDOWN_TIME INTEGER," + " MOUNT_TYPE INTEGER CONSTRAINT DRIVE_STATE_MT_NN NOT NULL," + " DRIVE_STATUS VARCHAR(100) DEFAULT 'UNKNOWN' CONSTRAINT DRIVE_STATE_DS_NN NOT NULL," + " DESIRED_UP CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DU_NN NOT NULL," + " DESIRED_FORCE_DOWN CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DFD_NN NOT NULL," + " REASON_UP_DOWN VARCHAR(1000)," + " CURRENT_VID VARCHAR(100)," + " CTA_VERSION VARCHAR(100)," + " CURRENT_PRIORITY INTEGER," + " CURRENT_ACTIVITY VARCHAR(100)," + " CURRENT_ACTIVITY_WEIGHT VARCHAR(100)," + " CURRENT_TAPE_POOL VARCHAR(100)," + " NEXT_MOUNT_TYPE INTEGER," + " NEXT_VID VARCHAR(100)," + " NEXT_TAPE_POOL VARCHAR(100)," + " NEXT_PRIORITY INTEGER," + " NEXT_ACTIVITY VARCHAR(100)," + " NEXT_ACTIVITY_WEIGHT VARCHAR(100)," + " DEV_FILE_NAME VARCHAR(100)," + " RAW_LIBRARY_SLOT VARCHAR(100)," + " CURRENT_VO VARCHAR(100)," + " NEXT_VO VARCHAR(100)," + " USER_COMMENT VARCHAR(1000)," + " CREATION_LOG_USER_NAME VARCHAR(100)," + " CREATION_LOG_HOST_NAME VARCHAR(100)," + " CREATION_LOG_TIME INTEGER," + " LAST_UPDATE_USER_NAME VARCHAR(100)," + " LAST_UPDATE_HOST_NAME VARCHAR(100)," + " LAST_UPDATE_TIME INTEGER," + " DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DSN_NN NOT NULL," + " RESERVED_BYTES INTEGER CONSTRAINT DRIVE_STATE_RB_NN NOT NULL," + " CONSTRAINT DRIVE_STATE_DN_PK PRIMARY KEY(DRIVE_NAME)," + " CONSTRAINT DRIVE_STATE_DU_BOOL_CK CHECK(DESIRED_UP IN ('0', '1'))," + " CONSTRAINT DRIVE_STATE_DFD_BOOL_CK CHECK(DESIRED_FORCE_DOWN IN ('0', '1'))," + " CONSTRAINT DRIVE_STATE_DS_STRING_CK CHECK(DRIVE_STATUS IN ('DOWN', 'UP', 'PROBING', 'STARTING'," + " 'MOUNTING', 'TRANSFERING', 'UNLOADING', 'UNMOUNTING', 'DRAININGTODISK', 'CLEANINGUP', 'SHUTDOWN'," + " 'UNKNOWN'))" + ");" + "INSERT INTO CTA_CATALOGUE(" + " SCHEMA_VERSION_MAJOR," + " SCHEMA_VERSION_MINOR," + " STATUS)" + "VALUES(" + " 4," + " 2," + " 'PRODUCTION');" + }, + {"postgres", "CREATE SEQUENCE ARCHIVE_FILE_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NO MAXVALUE" + " MINVALUE 1" + " NO CYCLE" + " CACHE 20;" + "CREATE SEQUENCE LOGICAL_LIBRARY_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NO MAXVALUE" + " MINVALUE 1" + " NO CYCLE" + " CACHE 20;" + "CREATE SEQUENCE MEDIA_TYPE_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NO MAXVALUE" + " MINVALUE 1" + " NO CYCLE" + " CACHE 20;" + "CREATE SEQUENCE STORAGE_CLASS_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NO MAXVALUE" + " MINVALUE 1" + " NO CYCLE" + " CACHE 20;" + "CREATE SEQUENCE TAPE_POOL_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NO MAXVALUE" + " MINVALUE 1" + " NO CYCLE" + " CACHE 20;" + "CREATE SEQUENCE VIRTUAL_ORGANIZATION_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NO MAXVALUE" + " MINVALUE 1" + " NO CYCLE" + " CACHE 20;" + "CREATE SEQUENCE FILE_RECYCLE_LOG_ID_SEQ" + " INCREMENT BY 1" + " START WITH 1" + " NO MAXVALUE" + " MINVALUE 1" + " NO CYCLE" + " CACHE 20;" + "CREATE TABLE CTA_CATALOGUE(" + " SCHEMA_VERSION_MAJOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM1_NN NOT NULL," + " SCHEMA_VERSION_MINOR NUMERIC(20, 0) CONSTRAINT CTA_CATALOGUE_SVM2_NN NOT NULL," + " NEXT_SCHEMA_VERSION_MAJOR NUMERIC(20, 0)," + " NEXT_SCHEMA_VERSION_MINOR NUMERIC(20, 0)," + " STATUS VARCHAR(100)," + " IS_PRODUCTION CHAR(1) DEFAULT '0' CONSTRAINT CTA_CATALOGUE_IP_NN NOT NULL," + " CONSTRAINT CTA_CATALOGUE_IP_BOOL_CK CHECK(IS_PRODUCTION IN ('0','1'))" + ");" + "CREATE TABLE ADMIN_USER(" + " ADMIN_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_AUN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ADMIN_USER_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ADMIN_USER_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ADMIN_USER_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ADMIN_USER_LUT_NN NOT NULL," + " CONSTRAINT ADMIN_USER_PK PRIMARY KEY(ADMIN_USER_NAME)" + ");" + "CREATE TABLE DISK_SYSTEM(" + " DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_DSNM_NN NOT NULL," + " FILE_REGEXP VARCHAR(100) CONSTRAINT DISK_SYSTEM_FR_NN NOT NULL," + " FREE_SPACE_QUERY_URL VARCHAR(1000) CONSTRAINT DISK_SYSTEM_FSQU_NN NOT NULL," + " REFRESH_INTERVAL NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_RI_NN NOT NULL," + " TARGETED_FREE_SPACE NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_TFS_NN NOT NULL," + " SLEEP_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_ST_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT DISK_SYSTEM_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT DISK_SYSTEM_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT DISK_SYSTEM_LUT_NN NOT NULL," + " CONSTRAINT NAME_PK PRIMARY KEY(DISK_SYSTEM_NAME)" + ");" + "CREATE TABLE VIRTUAL_ORGANIZATION(" + " VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_VOI_NN NOT NULL," + " VIRTUAL_ORGANIZATION_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL," + " READ_MAX_DRIVES NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL," + " WRITE_MAX_DRIVES NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL," + " MAX_FILE_SIZE NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT VIRTUAL_ORGANIZATION_LUT_NN NOT NULL," + " CONSTRAINT VIRTUAL_ORGANIZATION_PK PRIMARY KEY(VIRTUAL_ORGANIZATION_ID)," + " CONSTRAINT VIRTUAL_ORGANIZATION_VON_UN UNIQUE(VIRTUAL_ORGANIZATION_NAME)" + ");" + "CREATE TABLE STORAGE_CLASS(" + " STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_SCI_NN NOT NULL," + " STORAGE_CLASS_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_SCN_NN NOT NULL," + " NB_COPIES NUMERIC(3, 0) CONSTRAINT STORAGE_CLASS_NC_NN NOT NULL," + " VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_VOI_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT STORAGE_CLASS_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT STORAGE_CLASS_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT STORAGE_CLASS_LUT_NN NOT NULL," + " CONSTRAINT STORAGE_CLASS_PK PRIMARY KEY(STORAGE_CLASS_ID)," + " CONSTRAINT STORAGE_CLASS_SCN_UN UNIQUE(STORAGE_CLASS_NAME)," + " CONSTRAINT STORAGE_CLASS_VOI_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID)" + ");" + "CREATE TABLE TAPE_POOL(" + " TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT TAPE_POOL_TPI_NN NOT NULL," + " TAPE_POOL_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_TPN_NN NOT NULL," + " VIRTUAL_ORGANIZATION_ID NUMERIC(20, 0) CONSTRAINT TAPE_POOL_VOI_NN NOT NULL," + " NB_PARTIAL_TAPES NUMERIC(20, 0) CONSTRAINT TAPE_POOL_NPT_NN NOT NULL," + " IS_ENCRYPTED CHAR(1) CONSTRAINT TAPE_POOL_IE_NN NOT NULL," + " SUPPLY VARCHAR(100)," + " USER_COMMENT VARCHAR(1000) CONSTRAINT TAPE_POOL_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT TAPE_POOL_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_POOL_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_POOL_LUT_NN NOT NULL," + " CONSTRAINT TAPE_POOL_PK PRIMARY KEY(TAPE_POOL_ID)," + " CONSTRAINT TAPE_POOL_TPN_UN UNIQUE(TAPE_POOL_NAME)," + " CONSTRAINT TAPE_POOL_IS_ENCRYPTED_BOOL_CK CHECK(IS_ENCRYPTED IN ('0', '1'))," + " CONSTRAINT TAPE_POOL_VO_FK FOREIGN KEY(VIRTUAL_ORGANIZATION_ID) REFERENCES VIRTUAL_ORGANIZATION(VIRTUAL_ORGANIZATION_ID)" + ");" + "CREATE TABLE ARCHIVE_ROUTE(" + " STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_SCI_NN NOT NULL," + " COPY_NB NUMERIC(3, 0) CONSTRAINT ARCHIVE_ROUTE_CN_NN NOT NULL," + " TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_TPI_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ARCHIVE_ROUTE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ARCHIVE_ROUTE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_ROUTE_LUT_NN NOT NULL," + " CONSTRAINT ARCHIVE_ROUTE_PK PRIMARY KEY(STORAGE_CLASS_ID, COPY_NB)," + " CONSTRAINT ARCHIVE_ROUTE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)," + " CONSTRAINT ARCHIVE_ROUTE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," + " CONSTRAINT ARCHIVE_ROUTE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0)," + " CONSTRAINT ARCHIVE_ROUTE_SCI_TPI_UN UNIQUE(STORAGE_CLASS_ID, TAPE_POOL_ID)" + ");" + "CREATE TABLE MEDIA_TYPE(" + " MEDIA_TYPE_ID NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_MTI_NN NOT NULL," + " MEDIA_TYPE_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_MTN_NN NOT NULL," + " CARTRIDGE VARCHAR(100) CONSTRAINT MEDIA_TYPE_C_NN NOT NULL," + " CAPACITY_IN_BYTES NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_CIB_NN NOT NULL," + " PRIMARY_DENSITY_CODE NUMERIC(3, 0)," + " SECONDARY_DENSITY_CODE NUMERIC(3, 0)," + " NB_WRAPS NUMERIC(10, 0)," + " MIN_LPOS NUMERIC(20, 0)," + " MAX_LPOS NUMERIC(20, 0)," + " USER_COMMENT VARCHAR(1000) CONSTRAINT MEDIA_TYPE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MEDIA_TYPE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT MEDIA_TYPE_LUT_NN NOT NULL," + " CONSTRAINT MEDIA_TYPE_PK PRIMARY KEY(MEDIA_TYPE_ID)," + " CONSTRAINT MEDIA_TYPE_MTN_UN UNIQUE(MEDIA_TYPE_NAME)" + ");" + "CREATE TABLE LOGICAL_LIBRARY(" + " LOGICAL_LIBRARY_ID NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_LLI_NN NOT NULL," + " LOGICAL_LIBRARY_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LLN_NN NOT NULL," + " IS_DISABLED CHAR(1) DEFAULT '0' CONSTRAINT LOGICAL_LIBRARY_ID_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT LOGICAL_LIBRARY_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT LOGICAL_LIBRARY_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT LOGICAL_LIBRARY_LUT_NN NOT NULL," + " CONSTRAINT LOGICAL_LIBRARY_PK PRIMARY KEY(LOGICAL_LIBRARY_ID)," + " CONSTRAINT LOGICAL_LIBRARY_LLN_UN UNIQUE(LOGICAL_LIBRARY_NAME)," + " CONSTRAINT LOGICAL_LIBRARY_ID_BOOL_CK CHECK(IS_DISABLED IN ('0', '1'))" + ");" + "CREATE TABLE TAPE(" + " VID VARCHAR(100) CONSTRAINT TAPE_V_NN NOT NULL," + " MEDIA_TYPE_ID NUMERIC(20, 0) CONSTRAINT TAPE_MTID_NN NOT NULL," + " VENDOR VARCHAR(100) CONSTRAINT TAPE_V2_NN NOT NULL," + " LOGICAL_LIBRARY_ID NUMERIC(20, 0) CONSTRAINT TAPE_LLI_NN NOT NULL," + " TAPE_POOL_ID NUMERIC(20, 0) CONSTRAINT TAPE_TPI_NN NOT NULL," + " ENCRYPTION_KEY_NAME VARCHAR(100)," + " DATA_IN_BYTES NUMERIC(20, 0) CONSTRAINT TAPE_DIB_NN NOT NULL," + " LAST_FSEQ NUMERIC(20, 0) CONSTRAINT TAPE_LF_NN NOT NULL," + " NB_MASTER_FILES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_MASTER_FILES_NN NOT NULL," + " MASTER_DATA_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_MASTER_DATA_IN_BYTES_NN NOT NULL," + " IS_FULL CHAR(1) CONSTRAINT TAPE_IF_NN NOT NULL," + " IS_FROM_CASTOR CHAR(1) CONSTRAINT TAPE_IFC_NN NOT NULL," + " DIRTY CHAR(1) DEFAULT '1' CONSTRAINT TAPE_DIRTY_NN NOT NULL," + " NB_COPY_NB_1 NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_1_NN NOT NULL," + " COPY_NB_1_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_COPY_NB_1_IN_BYTES_NN NOT NULL," + " NB_COPY_NB_GT_1 NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_NB_COPY_NB_GT_1_NN NOT NULL," + " COPY_NB_GT_1_IN_BYTES NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_COPY_NB_GT_1_IN_BYTES_NN NOT NULL," + " LABEL_DRIVE VARCHAR(100)," + " LABEL_TIME NUMERIC(20, 0) ," + " LAST_READ_DRIVE VARCHAR(100)," + " LAST_READ_TIME NUMERIC(20, 0) ," + " LAST_WRITE_DRIVE VARCHAR(100)," + " LAST_WRITE_TIME NUMERIC(20, 0) ," + " READ_MOUNT_COUNT NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_RMC_NN NOT NULL," + " WRITE_MOUNT_COUNT NUMERIC(20, 0) DEFAULT 0 CONSTRAINT TAPE_WMC_NN NOT NULL," + " USER_COMMENT VARCHAR(1000)," + " TAPE_STATE VARCHAR(100) CONSTRAINT TAPE_TS_NN NOT NULL," + " STATE_REASON VARCHAR(1000)," + " STATE_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_SUT_NN NOT NULL," + " STATE_MODIFIED_BY VARCHAR(100) CONSTRAINT TAPE_SMB_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT TAPE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT TAPE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT TAPE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT TAPE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT TAPE_LUT_NN NOT NULL," + " CONSTRAINT TAPE_PK PRIMARY KEY(VID)," + " CONSTRAINT TAPE_LOGICAL_LIBRARY_FK FOREIGN KEY(LOGICAL_LIBRARY_ID) REFERENCES LOGICAL_LIBRARY(LOGICAL_LIBRARY_ID)," + " CONSTRAINT TAPE_TAPE_POOL_FK FOREIGN KEY(TAPE_POOL_ID) REFERENCES TAPE_POOL(TAPE_POOL_ID)," + " CONSTRAINT TAPE_IS_FULL_BOOL_CK CHECK(IS_FULL IN ('0', '1'))," + " CONSTRAINT TAPE_IS_FROM_CASTOR_BOOL_CK CHECK(IS_FROM_CASTOR IN ('0', '1'))," + " CONSTRAINT TAPE_DIRTY_BOOL_CK CHECK(DIRTY IN ('0','1'))," + " CONSTRAINT TAPE_STATE_CK CHECK(TAPE_STATE IN ('ACTIVE', 'DISABLED', 'BROKEN'))," + " CONSTRAINT TAPE_MEDIA_TYPE_FK FOREIGN KEY(MEDIA_TYPE_ID) REFERENCES MEDIA_TYPE(MEDIA_TYPE_ID)" + ");" + "CREATE INDEX TAPE_TAPE_POOL_ID_IDX ON TAPE(TAPE_POOL_ID);" + "CREATE INDEX TAPE_STATE_IDX ON TAPE(TAPE_STATE);" + "CREATE TABLE MOUNT_POLICY(" + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_MPN_NN NOT NULL," + " ARCHIVE_PRIORITY NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_AP_NN NOT NULL," + " ARCHIVE_MIN_REQUEST_AGE NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_AMRA_NN NOT NULL," + " RETRIEVE_PRIORITY NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_RP_NN NOT NULL," + " RETRIEVE_MIN_REQUEST_AGE NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_RMRA_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT MOUNT_POLICY_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT MOUNT_POLICY_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT MOUNT_POLICY_LUT_NN NOT NULL," + " CONSTRAINT MOUNT_POLICY_PK PRIMARY KEY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE REQUESTER_MOUNT_RULE(" + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_DIN_NN NOT NULL," + " REQUESTER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_RN_NN NOT NULL," + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_MPN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_RULE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_RULE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_RULE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_RULE_LUT_NN NOT NULL," + " CONSTRAINT RQSTER_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_NAME)," + " CONSTRAINT RQSTER_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME)" + " REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE REQUESTER_GROUP_MOUNT_RULE(" + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_DIN_NN NOT NULL," + " REQUESTER_GROUP_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_RGN_NN NOT NULL," + " MOUNT_POLICY_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_MPN_NN NOT NULL," + " USER_COMMENT VARCHAR(1000) CONSTRAINT RQSTER_GRP_RULE_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_GRP_RULE_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT RQSTER_GRP_RULE_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT RQSTER_GRP_RULE_LUT_NN NOT NULL," + " CONSTRAINT RQSTER_GRP_RULE_PK PRIMARY KEY(DISK_INSTANCE_NAME, REQUESTER_GROUP_NAME)," + " CONSTRAINT RQSTER_GRP_RULE_MNT_PLC_FK FOREIGN KEY(MOUNT_POLICY_NAME)" + " REFERENCES MOUNT_POLICY(MOUNT_POLICY_NAME)" + ");" + "CREATE TABLE ARCHIVE_FILE(" + " ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_AFI_NN NOT NULL," + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DIN_NN NOT NULL," + " DISK_FILE_ID VARCHAR(100) CONSTRAINT ARCHIVE_FILE_DFI_NN NOT NULL," + " DISK_FILE_UID NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_DFUID_NN NOT NULL," + " DISK_FILE_GID NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_DFGID_NN NOT NULL," + " SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SIB_NN NOT NULL," + " CHECKSUM_BLOB BYTEA," + " CHECKSUM_ADLER32 NUMERIC(10, 0) CONSTRAINT ARCHIVE_FILE_CB2_NN NOT NULL," + " STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_SCI_NN NOT NULL," + " CREATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_CT2_NN NOT NULL," + " RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT ARCHIVE_FILE_RT_NN NOT NULL," + " IS_DELETED CHAR(1) DEFAULT '0' CONSTRAINT ARCHIVE_FILE_ID_NN NOT NULL," + " COLLOCATION_HINT VARCHAR(100)," + " CONSTRAINT ARCHIVE_FILE_PK PRIMARY KEY(ARCHIVE_FILE_ID)," + " CONSTRAINT ARCHIVE_FILE_STORAGE_CLASS_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)," + " CONSTRAINT ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID)," + " CONSTRAINT ARCHIVE_FILE_ID_BOOL_CK CHECK(IS_DELETED IN ('0', '1'))" + ");" + "CREATE INDEX ARCHIVE_FILE_DIN_IDX ON ARCHIVE_FILE(DISK_INSTANCE_NAME);" + "CREATE INDEX ARCHIVE_FILE_DFI_IDX ON ARCHIVE_FILE(DISK_FILE_ID);" + "CREATE TABLE TAPE_FILE(" + " VID VARCHAR(100) CONSTRAINT TAPE_FILE_V_NN NOT NULL," + " FSEQ NUMERIC(20, 0) CONSTRAINT TAPE_FILE_F_NN NOT NULL," + " BLOCK_ID NUMERIC(20, 0) CONSTRAINT TAPE_FILE_BI_NN NOT NULL," + " LOGICAL_SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CSIB_NN NOT NULL," + " COPY_NB NUMERIC(3, 0) CONSTRAINT TAPE_FILE_CN_NN NOT NULL," + " CREATION_TIME NUMERIC(20, 0) CONSTRAINT TAPE_FILE_CT_NN NOT NULL," + " ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT TAPE_FILE_AFI_NN NOT NULL," + " CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ)," + " CONSTRAINT TAPE_FILE_TAPE_FK FOREIGN KEY(VID)" + " REFERENCES TAPE(VID)," + " CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID)" + " REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID)," + " CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID)," + " CONSTRAINT TAPE_FILE_COPY_NB_GT_0_CK CHECK(COPY_NB > 0)" + ");" + "CREATE INDEX TAPE_FILE_VID_IDX ON TAPE_FILE(VID);" + "CREATE INDEX TAPE_FILE_ARCHIVE_FILE_ID_IDX ON TAPE_FILE(ARCHIVE_FILE_ID);" + "CREATE TABLE ACTIVITIES_WEIGHTS (" + " DISK_INSTANCE_NAME VARCHAR(100)," + " ACTIVITY VARCHAR(100)," + " WEIGHT VARCHAR(100)," + " USER_COMMENT VARCHAR(1000) CONSTRAINT ACTIV_WEIGHTS_UC_NN NOT NULL," + " CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLUN_NN NOT NULL," + " CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_CLHN_NN NOT NULL," + " CREATION_LOG_TIME NUMERIC(20, 0) CONSTRAINT ACTIV_WEIGHTS_CLT_NN NOT NULL," + " LAST_UPDATE_USER_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUUN_NN NOT NULL," + " LAST_UPDATE_HOST_NAME VARCHAR(100) CONSTRAINT ACTIV_WEIGHTS_LUHN_NN NOT NULL," + " LAST_UPDATE_TIME NUMERIC(20, 0) CONSTRAINT ACTIV_WEIGHTS_LUT_NN NOT NULL" + ");" + "CREATE TABLE FILE_RECYCLE_LOG(" + " FILE_RECYCLE_LOG_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_ID_NN NOT NULL," + " VID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_VID_NN NOT NULL," + " FSEQ NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_FSEQ_NN NOT NULL," + " BLOCK_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_BID_NN NOT NULL," + " COPY_NB NUMERIC(3, 0) CONSTRAINT FILE_RECYCLE_LOG_COPY_NB_NN NOT NULL," + " TAPE_FILE_CREATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_TFCT_NN NOT NULL," + " ARCHIVE_FILE_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_AFI_NN NOT NULL," + " DISK_INSTANCE_NAME VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DIN_NN NOT NULL," + " DISK_FILE_ID VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFI_NN NOT NULL," + " DISK_FILE_ID_WHEN_DELETED VARCHAR(100) CONSTRAINT FILE_RECYCLE_LOG_DFIWD_NN NOT NULL," + " DISK_FILE_UID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_DFU_NN NOT NULL," + " DISK_FILE_GID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_DFG_NN NOT NULL," + " SIZE_IN_BYTES NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_SIB_NN NOT NULL," + " CHECKSUM_BLOB BYTEA," + " CHECKSUM_ADLER32 NUMERIC(10, 0) CONSTRAINT FILE_RECYCLE_LOG_CA_NN NOT NULL," + " STORAGE_CLASS_ID NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_SCI_NN NOT NULL," + " ARCHIVE_FILE_CREATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYLE_LOG_CT_NN NOT NULL," + " RECONCILIATION_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_RT_NN NOT NULL," + " COLLOCATION_HINT VARCHAR(100)," + " DISK_FILE_PATH VARCHAR(2000)," + " REASON_LOG VARCHAR(1000) CONSTRAINT FILE_RECYCLE_LOG_RL_NN NOT NULL," + " RECYCLE_LOG_TIME NUMERIC(20, 0) CONSTRAINT FILE_RECYCLE_LOG_RLT_NN NOT NULL," + " CONSTRAINT FILE_RECYCLE_LOG_PK PRIMARY KEY(FILE_RECYCLE_LOG_ID)," + " CONSTRAINT FILE_RECYCLE_LOG_VID_FK FOREIGN KEY(VID) REFERENCES TAPE(VID)," + " CONSTRAINT FILE_RECYCLE_LOG_SC_FK FOREIGN KEY(STORAGE_CLASS_ID) REFERENCES STORAGE_CLASS(STORAGE_CLASS_ID)" + ");" + "CREATE INDEX FILE_RECYCLE_LOG_DFI_IDX ON FILE_RECYCLE_LOG(DISK_FILE_ID);" + "" + "CREATE TABLE DRIVE_CONFIG (" + " DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_DN_NN NOT NULL," + " CATEGORY VARCHAR(100) CONSTRAINT DRIVE_CONFIG_C_NN NOT NULL," + " KEY_NAME VARCHAR(100) CONSTRAINT DRIVE_CONFIG_KN_NN NOT NULL," + " VALUE VARCHAR(1000) CONSTRAINT DRIVE_CONFIG_V_NN NOT NULL," + " SOURCE VARCHAR(100) CONSTRAINT DRIVE_CONFIG_S_NN NOT NULL," + " CONSTRAINT DRIVE_CONFIG_DN_PK PRIMARY KEY(KEY_NAME, DRIVE_NAME)" + ");" + "" + "CREATE TABLE TAPE_DRIVE (" + " DRIVE_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DN_NN NOT NULL," + " HOST VARCHAR(100) CONSTRAINT DRIVE_STATE_H_NN NOT NULL," + " LOGICAL_LIBRARY VARCHAR(100) CONSTRAINT DRIVE_STATE_LL_NN NOT NULL," + " SESSION_ID NUMERIC(20, 0)," + " BYTES_TRANSFERED_IN_SESSION NUMERIC(20, 0)," + " FILES_TRANSFERED_IN_SESSION NUMERIC(20, 0)," + " LATEST_BANDWIDTH VARCHAR(100)," + " SESSION_START_TIME NUMERIC(20, 0)," + " MOUNT_START_TIME NUMERIC(20, 0)," + " TRANSFER_START_TIME NUMERIC(20, 0)," + " UNLOAD_START_TIME NUMERIC(20, 0)," + " UNMOUNT_START_TIME NUMERIC(20, 0)," + " DRAINING_START_TIME NUMERIC(20, 0)," + " DOWN_OR_UP_START_TIME NUMERIC(20, 0)," + " PROBE_START_TIME NUMERIC(20, 0)," + " CLEANUP_START_TIME NUMERIC(20, 0)," + " START_START_TIME NUMERIC(20, 0)," + " SHUTDOWN_TIME NUMERIC(20, 0)," + " MOUNT_TYPE NUMERIC(10, 0) CONSTRAINT DRIVE_STATE_MT_NN NOT NULL," + " DRIVE_STATUS VARCHAR(100) DEFAULT 'UNKNOWN' CONSTRAINT DRIVE_STATE_DS_NN NOT NULL," + " DESIRED_UP CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DU_NN NOT NULL," + " DESIRED_FORCE_DOWN CHAR(1) DEFAULT '0' CONSTRAINT DRIVE_STATE_DFD_NN NOT NULL," + " REASON_UP_DOWN VARCHAR(1000)," + " CURRENT_VID VARCHAR(100)," + " CTA_VERSION VARCHAR(100)," + " CURRENT_PRIORITY NUMERIC(20, 0)," + " CURRENT_ACTIVITY VARCHAR(100)," + " CURRENT_ACTIVITY_WEIGHT VARCHAR(100)," + " CURRENT_TAPE_POOL VARCHAR(100)," + " NEXT_MOUNT_TYPE NUMERIC(10, 0)," + " NEXT_VID VARCHAR(100)," + " NEXT_TAPE_POOL VARCHAR(100)," + " NEXT_PRIORITY NUMERIC(20, 0)," + " NEXT_ACTIVITY VARCHAR(100)," + " NEXT_ACTIVITY_WEIGHT VARCHAR(100)," + " DEV_FILE_NAME VARCHAR(100)," + " RAW_LIBRARY_SLOT VARCHAR(100)," + " CURRENT_VO VARCHAR(100)," + " NEXT_VO VARCHAR(100)," + " USER_COMMENT VARCHAR(1000)," + " CREATION_LOG_USER_NAME VARCHAR(100)," + " CREATION_LOG_HOST_NAME VARCHAR(100)," + " CREATION_LOG_TIME NUMERIC(20, 0)," + " LAST_UPDATE_USER_NAME VARCHAR(100)," + " LAST_UPDATE_HOST_NAME VARCHAR(100)," + " LAST_UPDATE_TIME NUMERIC(20, 0)," + " DISK_SYSTEM_NAME VARCHAR(100) CONSTRAINT DRIVE_STATE_DSN_NN NOT NULL," + " RESERVED_BYTES NUMERIC(20, 0) CONSTRAINT DRIVE_STATE_RB_NN NOT NULL," + " CONSTRAINT DRIVE_STATE_DN_PK PRIMARY KEY(DRIVE_NAME)," + " CONSTRAINT DRIVE_STATE_DU_BOOL_CK CHECK(DESIRED_UP IN ('0', '1'))," + " CONSTRAINT DRIVE_STATE_DFD_BOOL_CK CHECK(DESIRED_FORCE_DOWN IN ('0', '1'))," + " CONSTRAINT DRIVE_STATE_DS_STRING_CK CHECK(DRIVE_STATUS IN ('DOWN', 'UP', 'PROBING', 'STARTING'," + " 'MOUNTING', 'TRANSFERING', 'UNLOADING', 'UNMOUNTING', 'DRAININGTODISK', 'CLEANINGUP', 'SHUTDOWN'," + " 'UNKNOWN'))" + ");" + "INSERT INTO CTA_CATALOGUE(" + " SCHEMA_VERSION_MAJOR," + " SCHEMA_VERSION_MINOR," + " STATUS)" + "VALUES(" + " 4," + " 2," + " 'PRODUCTION');" + "ALTER TABLE ARCHIVE_FILE DROP CONSTRAINT" + " ARCHIVE_FILE_DIN_DFI_UN;" + "ALTER TABLE ARCHIVE_FILE ADD CONSTRAINT" + " ARCHIVE_FILE_DIN_DFI_UN UNIQUE(DISK_INSTANCE_NAME, DISK_FILE_ID) DEFERRABLE INITIALLY IMMEDIATE;" + "ALTER TABLE CTA_CATALOGUE ADD CONSTRAINT" + " CATALOGUE_STATUS_CONTENT_CK CHECK((NEXT_SCHEMA_VERSION_MAJOR IS NULL AND NEXT_SCHEMA_VERSION_MINOR IS NULL AND STATUS='PRODUCTION') OR (STATUS='UPGRADING'));" + }, + } }, }; }} diff --git a/catalogue/Catalogue.hpp b/catalogue/Catalogue.hpp index 2e8aa1358ff1f97413e57764165fcdf5546c6fdf..2d7426a353f201b3dce8ace99803b9e29c333455 100644 --- a/catalogue/Catalogue.hpp +++ b/catalogue/Catalogue.hpp @@ -124,6 +124,7 @@ CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedStorageClassUsedByArchiveFiles); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedStorageClassUsedByArchiveRoutes); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedStorageClassUsedByFileRecycleLogs); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedTapePoolUsedInAnArchiveRoute); +CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedExistingDeletedFileCopy); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedANonExistentTapeState); CTA_GENERATE_USER_EXCEPTION_CLASS(UserSpecifiedAnEmptyStringReasonWhenTapeStateNotActive); @@ -333,6 +334,14 @@ public: */ virtual void modifyVirtualOrganizationWriteMaxDrives(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t writeMaxDrives) = 0; + /** + * Modifies the max size of files for the specified Virtual Organization + * + * @param voName the VO name + * @param maxFileSize the new max file size for the specified Virtual Organization + */ + virtual void modifyVirtualOrganizationMaxFileSize(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t maxFileSize) = 0; + /** * Modifies the comment of the specified Virtual Organization * @@ -359,6 +368,8 @@ public: virtual void deleteStorageClass(const std::string &storageClassName) = 0; virtual std::list<common::dataStructures::StorageClass> getStorageClasses() const = 0; + virtual common::dataStructures::StorageClass getStorageClass(const std::string &name) const = 0; + virtual void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const uint64_t nbCopies) = 0; virtual void modifyStorageClassComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) = 0; virtual void modifyStorageClassVo(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo) = 0; @@ -902,6 +913,15 @@ public: */ virtual FileRecycleLogItor getFileRecycleLogItor(const RecycleTapeFileSearchCriteria & searchCriteria = RecycleTapeFileSearchCriteria()) const = 0; + + /** + * Restores the deleted files in the Recycle log that match the criteria passed + * + * @param searchCriteria The search criteria + */ + virtual void restoreFilesInRecycleLog(const RecycleTapeFileSearchCriteria & searchCriteria = RecycleTapeFileSearchCriteria()) = 0; + + /** * Returns the specified files in tape file sequence order. * @@ -970,6 +990,7 @@ public: const std::string &reason) = 0; + /** * Returns the archive file with the specified unique identifier. * diff --git a/catalogue/CatalogueRetryWrapper.hpp b/catalogue/CatalogueRetryWrapper.hpp index e64e0426359a75951485951810de76e8518f1e33..aa0aed2d9de95ddec15d7c2726c93c63a9de40cb 100644 --- a/catalogue/CatalogueRetryWrapper.hpp +++ b/catalogue/CatalogueRetryWrapper.hpp @@ -147,6 +147,9 @@ public: return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyVirtualOrganizationWriteMaxDrives(admin,voName,writeMaxDrives);}, m_maxTriesToConnect); } + void modifyVirtualOrganizationMaxFileSize(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t maxFileSize) override { + return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyVirtualOrganizationMaxFileSize(admin,voName,maxFileSize);}, m_maxTriesToConnect); + } void modifyVirtualOrganizationComment(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const std::string &comment) override { @@ -165,6 +168,10 @@ public: return retryOnLostConnection(m_log, [&]{return m_catalogue->getStorageClasses();}, m_maxTriesToConnect); } + common::dataStructures::StorageClass getStorageClass(const std::string &name) const override { + return retryOnLostConnection(m_log, [&]{return m_catalogue->getStorageClass(name);}, m_maxTriesToConnect); + } + void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const uint64_t nbCopies) override { return retryOnLostConnection(m_log, [&]{return m_catalogue->modifyStorageClassNbCopies(admin, name, nbCopies);}, m_maxTriesToConnect); } @@ -533,6 +540,10 @@ public: return retryOnLostConnection(m_log, [&]{return m_catalogue->getFileRecycleLogItor(searchCriteria);}, m_maxTriesToConnect); } + void restoreFilesInRecycleLog(const RecycleTapeFileSearchCriteria & searchCriteria) override { + return retryOnLostConnection(m_log, [&]{return m_catalogue->restoreFilesInRecycleLog(searchCriteria);}, m_maxTriesToConnect); + } + void deleteFileFromRecycleBin(const uint64_t archiveFileId, log::LogContext &lc){ return retryOnLostConnection(m_log,[&]{return m_catalogue->deleteFileFromRecycleBin(archiveFileId,lc);},m_maxTriesToConnect); } diff --git a/catalogue/CatalogueTest.cpp b/catalogue/CatalogueTest.cpp index bdd6bf47e1b2e0278fcc4250139353812d3b8340..1660e54594d5fe023653b09ce5b3cb9418dbeb7f 100644 --- a/catalogue/CatalogueTest.cpp +++ b/catalogue/CatalogueTest.cpp @@ -81,6 +81,7 @@ namespace { vo.comment = "Creation of virtual organization vo"; vo.readMaxDrives = 1; vo.writeMaxDrives = 1; + vo.maxFileSize = 0; return vo; } @@ -92,6 +93,7 @@ namespace { vo.comment = "Creation of another virtual organization vo"; vo.readMaxDrives = 1; vo.writeMaxDrives = 1; + vo.maxFileSize = 0; return vo; } @@ -128,6 +130,17 @@ namespace { return storageClass; } + cta::common::dataStructures::StorageClass getStorageClassTripleCopy() { + using namespace cta; + + common::dataStructures::StorageClass storageClass; + storageClass.name = "storage_class_triple_copy"; + storageClass.nbCopies = 3; + storageClass.vo.name = getVo().name; + storageClass.comment = "Creation of storage class with 3 copies on tape"; + return storageClass; + } + cta::catalogue::MediaType getMediaType() { using namespace cta; @@ -169,6 +182,14 @@ namespace { return tape; } + cta::catalogue::CreateTapeAttributes getTape3() { + // Tape 3 is an exact copy of tape 1 except for its VID and comment + auto tape = getTape1(); + tape.vid = "VIDTHREE"; + tape.comment = "Creation of tape three"; + return tape; + } + cta::catalogue::CreateMountPolicyAttributes getMountPolicy1() { using namespace cta; @@ -261,9 +282,11 @@ cta_catalogue_CatalogueTest::cta_catalogue_CatalogueTest(): m_storageClassSingleCopy(getStorageClass()), m_anotherStorageClass(getAnotherStorageClass()), m_storageClassDualCopy(getStorageClassDualCopy()), + m_storageClassTripleCopy(getStorageClassTripleCopy()), m_mediaType(getMediaType()), m_tape1(getTape1()), - m_tape2(getTape2()) { + m_tape2(getTape2()), + m_tape3(getTape3()) { } //------------------------------------------------------------------------------ @@ -8891,6 +8914,17 @@ TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_non_existance_archiveFileId) ASSERT_THROW(m_catalogue->getArchiveFilesItor(searchCriteria), exception::UserError); } +TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_fSeq_without_vid) { + using namespace cta; + + ASSERT_FALSE(m_catalogue->getArchiveFilesItor().hasMore()); + + catalogue::TapeFileSearchCriteria searchCriteria; + searchCriteria.fSeq = 1234; + + ASSERT_THROW(m_catalogue->getArchiveFilesItor(searchCriteria), exception::UserError); +} + TEST_P(cta_catalogue_CatalogueTest, getArchiveFiles_disk_file_id_without_instance) { using namespace cta; @@ -15195,6 +15229,24 @@ TEST_P(cta_catalogue_CatalogueTest, modifyVirtualOrganizationWriteMaxDrives) { ASSERT_THROW(m_catalogue->modifyVirtualOrganizationWriteMaxDrives(m_admin,"DOES not exists",writeMaxDrives),cta::exception::UserError); } +TEST_P(cta_catalogue_CatalogueTest, modifyVirtualOrganizationMaxFileSize) { + using namespace cta; + + common::dataStructures::VirtualOrganization vo = getVo(); + + ASSERT_NO_THROW(m_catalogue->createVirtualOrganization(m_admin,vo)); + + uint64_t maxFileSize = 1; + ASSERT_NO_THROW(m_catalogue->modifyVirtualOrganizationMaxFileSize(m_admin,vo.name,maxFileSize)); + + auto vos = m_catalogue->getVirtualOrganizations(); + auto &frontVo = vos.front(); + + ASSERT_EQ(maxFileSize,frontVo.maxFileSize); + + ASSERT_THROW(m_catalogue->modifyVirtualOrganizationMaxFileSize(m_admin,"DOES not exists", maxFileSize),cta::exception::UserError); +} + TEST_P(cta_catalogue_CatalogueTest, getVirtualOrganizationOfTapepool) { using namespace cta; @@ -15808,9 +15860,9 @@ TEST_P(cta_catalogue_CatalogueTest, filesArePutInTheFileRecycleLogInsteadOfBeing criteria.diskFileIds = std::vector<std::string>(); criteria.diskFileIds->push_back(diskFileId); criteria.vid = tape1.vid; - + auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(criteria); - + ASSERT_TRUE(fileRecycleLogItor.hasMore()); auto fileRecycleLog = fileRecycleLogItor.next(); ASSERT_EQ(archiveFileId, fileRecycleLog.archiveFileId); @@ -15818,7 +15870,7 @@ TEST_P(cta_catalogue_CatalogueTest, filesArePutInTheFileRecycleLogInsteadOfBeing ASSERT_EQ(copynb, fileRecycleLog.copyNb); ASSERT_EQ(tape1.vid, fileRecycleLog.vid); ASSERT_EQ(diskInstance, fileRecycleLog.diskInstanceName); - + ASSERT_FALSE(fileRecycleLogItor.hasMore()); } } @@ -16247,7 +16299,7 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyUsingArchiveID) { // Write a file on tape { std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; - + std::ostringstream diskFileId; diskFileId << 12345677; @@ -16271,14 +16323,14 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyUsingArchiveID) { fileWritten.copyNb = 1; fileWritten.tapeDrive = tapeDrive; tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); - + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); } - + // Write a second copy of file on tape { std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; - + std::ostringstream diskFileId; diskFileId << 12345677; @@ -16302,19 +16354,19 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyUsingArchiveID) { fileWritten.copyNb = 2; fileWritten.tapeDrive = tapeDrive; tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); - + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); } { //Assert both copies written - auto archiveFile = m_catalogue->getArchiveFileById(1); + auto archiveFile = m_catalogue->getArchiveFileById(1); ASSERT_EQ(2, archiveFile.tapeFiles.size()); } { //delete copy of file on tape1 m_catalogue->deleteTapeFileCopy(tape1.vid, 1, reason); - auto archiveFile = m_catalogue->getArchiveFileById(1); + auto archiveFile = m_catalogue->getArchiveFileById(1); ASSERT_EQ(1, archiveFile.tapeFiles.size()); auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(); ASSERT_TRUE(fileRecycleLogItor.hasMore()); @@ -16332,7 +16384,7 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyUsingArchiveID) { { //delete last copy of file should fail ASSERT_THROW(m_catalogue->deleteTapeFileCopy(tape2.vid, 1, "reason"), exception::UserError); - + } } @@ -16367,7 +16419,7 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyDoesNotExist) { { //delete copy of file that does not exist should fail ASSERT_THROW(m_catalogue->deleteTapeFileCopy(tape2.vid, 1, reason), exception::UserError); - + } } @@ -16406,7 +16458,7 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyUsingFXID) { // Write a file on tape { std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; - + std::ostringstream diskFileId; diskFileId << 12345677; @@ -16430,14 +16482,14 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyUsingFXID) { fileWritten.copyNb = 1; fileWritten.tapeDrive = tapeDrive; tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); - + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); } - + // Write a second copy of file on tape { std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; - + std::ostringstream diskFileId; diskFileId << 12345677; @@ -16461,19 +16513,19 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyUsingFXID) { fileWritten.copyNb = 2; fileWritten.tapeDrive = tapeDrive; tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); - + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); } { //Assert both copies written - auto archiveFile = m_catalogue->getArchiveFileById(1); + auto archiveFile = m_catalogue->getArchiveFileById(1); ASSERT_EQ(2, archiveFile.tapeFiles.size()); } { //delete copy of file on tape1 m_catalogue->deleteTapeFileCopy(tape1.vid, "BC614D", diskInstance, reason); - auto archiveFile = m_catalogue->getArchiveFileById(1); + auto archiveFile = m_catalogue->getArchiveFileById(1); ASSERT_EQ(1, archiveFile.tapeFiles.size()); auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(); ASSERT_TRUE(fileRecycleLogItor.hasMore()); @@ -16490,8 +16542,456 @@ TEST_P(cta_catalogue_CatalogueTest, DeleteTapeFileCopyUsingFXID) { { //delete last copy of file should fail - ASSERT_THROW(m_catalogue->deleteTapeFileCopy(tape2.vid, "BC614D", diskInstance, reason), exception::UserError); + ASSERT_THROW(m_catalogue->deleteTapeFileCopy(tape2.vid, "BC614D", diskInstance, reason), exception::UserError); } } +TEST_P(cta_catalogue_CatalogueTest, RestoreTapeFileCopy) { + using namespace cta; + + const bool logicalLibraryIsDisabled= false; + const std::string tapePoolName1 = "tape_pool_name_1"; + const std::string tapePoolName2 = "tape_pool_name_2"; + const uint64_t nbPartialTapes = 1; + const bool isEncrypted = true; + const cta::optional<std::string> supply("value for the supply pool mechanism"); + const std::string diskInstance = "disk_instance"; + const std::string tapeDrive = "tape_drive"; + const std::string reason = "reason"; + + m_catalogue->createMediaType(m_admin, m_mediaType); + m_catalogue->createLogicalLibrary(m_admin, m_tape1.logicalLibraryName, logicalLibraryIsDisabled, "Create logical library"); + m_catalogue->createVirtualOrganization(m_admin, m_vo); + m_catalogue->createTapePool(m_admin, tapePoolName1, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool"); + m_catalogue->createTapePool(m_admin, tapePoolName2, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool"); + m_catalogue->createStorageClass(m_admin, m_storageClassDualCopy); + + auto tape1 = m_tape1; + auto tape2 = m_tape2; + tape1.tapePoolName = tapePoolName1; + tape2.tapePoolName = tapePoolName2; + + m_catalogue->createTape(m_admin, tape1); + m_catalogue->createTape(m_admin, tape2); + + ASSERT_FALSE(m_catalogue->getArchiveFilesItor().hasMore()); + const uint64_t archiveFileSize = 2 * 1000 * 1000 * 1000; + + + // Write a file on tape + { + std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; + + std::ostringstream diskFileId; + diskFileId << 12345677; + + std::ostringstream diskFilePath; + diskFilePath << "/test/file1"; + + auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>(); + auto & fileWritten = *fileWrittenUP; + fileWritten.archiveFileId = 1; + fileWritten.diskInstance = diskInstance; + fileWritten.diskFileId = diskFileId.str(); + fileWritten.diskFilePath = diskFilePath.str(); + fileWritten.diskFileOwnerUid = PUBLIC_DISK_USER; + fileWritten.diskFileGid = PUBLIC_DISK_GROUP; + fileWritten.size = archiveFileSize; + fileWritten.checksumBlob.insert(checksum::ADLER32, "1357"); + fileWritten.storageClassName = m_storageClassDualCopy.name; + fileWritten.vid = tape1.vid; + fileWritten.fSeq = 1; + fileWritten.blockId = 1 * 100; + fileWritten.copyNb = 1; + fileWritten.tapeDrive = tapeDrive; + tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); + + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); + } + + // Write a second copy of file on tape + { + std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; + + std::ostringstream diskFileId; + diskFileId << 12345677; + + std::ostringstream diskFilePath; + diskFilePath << "/test/file1"; + + auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>(); + auto & fileWritten = *fileWrittenUP; + fileWritten.archiveFileId = 1; + fileWritten.diskInstance = diskInstance; + fileWritten.diskFileId = diskFileId.str(); + fileWritten.diskFilePath = diskFilePath.str(); + fileWritten.diskFileOwnerUid = PUBLIC_DISK_USER; + fileWritten.diskFileGid = PUBLIC_DISK_GROUP; + fileWritten.size = archiveFileSize; + fileWritten.checksumBlob.insert(checksum::ADLER32, "1357"); + fileWritten.storageClassName = m_storageClassDualCopy.name; + fileWritten.vid = tape2.vid; + fileWritten.fSeq = 1; + fileWritten.blockId = 1 * 100; + fileWritten.copyNb = 2; + fileWritten.tapeDrive = tapeDrive; + tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); + + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); + } + { + //Assert both copies written + auto archiveFile = m_catalogue->getArchiveFileById(1); + ASSERT_EQ(2, archiveFile.tapeFiles.size()); + } + + { + //delete copy of file on tape1 + m_catalogue->deleteTapeFileCopy(tape1.vid, "BC614D", diskInstance, reason); + auto archiveFile = m_catalogue->getArchiveFileById(1); + ASSERT_EQ(1, archiveFile.tapeFiles.size()); + } + + + { + //restore copy of file on tape1 + catalogue::RecycleTapeFileSearchCriteria searchCriteria; + searchCriteria.archiveFileId = 1; + searchCriteria.vid = tape1.vid; + + m_catalogue->restoreFilesInRecycleLog(searchCriteria); + auto archiveFile = m_catalogue->getArchiveFileById(1); + //assert both copies present + ASSERT_EQ(2, archiveFile.tapeFiles.size()); + + //assert recycle log is empty + auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(); + ASSERT_FALSE(fileRecycleLogItor.hasMore()); + + } +} + +TEST_P(cta_catalogue_CatalogueTest, RestoreRewrittenTapeFileCopyFails) { + using namespace cta; + + const bool logicalLibraryIsDisabled= false; + const std::string tapePoolName1 = "tape_pool_name_1"; + const std::string tapePoolName2 = "tape_pool_name_2"; + const uint64_t nbPartialTapes = 1; + const bool isEncrypted = true; + const cta::optional<std::string> supply("value for the supply pool mechanism"); + const std::string diskInstance = "disk_instance"; + const std::string tapeDrive = "tape_drive"; + const std::string reason = "reason"; + + m_catalogue->createMediaType(m_admin, m_mediaType); + m_catalogue->createLogicalLibrary(m_admin, m_tape1.logicalLibraryName, logicalLibraryIsDisabled, "Create logical library"); + m_catalogue->createVirtualOrganization(m_admin, m_vo); + m_catalogue->createTapePool(m_admin, tapePoolName1, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool"); + m_catalogue->createTapePool(m_admin, tapePoolName2, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool"); + m_catalogue->createStorageClass(m_admin, m_storageClassDualCopy); + + auto tape1 = m_tape1; + auto tape2 = m_tape2; + tape1.tapePoolName = tapePoolName1; + tape2.tapePoolName = tapePoolName2; + + m_catalogue->createTape(m_admin, tape1); + m_catalogue->createTape(m_admin, tape2); + + ASSERT_FALSE(m_catalogue->getArchiveFilesItor().hasMore()); + const uint64_t archiveFileSize = 2 * 1000 * 1000 * 1000; + + + // Write a file on tape + { + std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; + + std::ostringstream diskFileId; + diskFileId << 12345677; + + std::ostringstream diskFilePath; + diskFilePath << "/test/file1"; + + auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>(); + auto & fileWritten = *fileWrittenUP; + fileWritten.archiveFileId = 1; + fileWritten.diskInstance = diskInstance; + fileWritten.diskFileId = diskFileId.str(); + fileWritten.diskFilePath = diskFilePath.str(); + fileWritten.diskFileOwnerUid = PUBLIC_DISK_USER; + fileWritten.diskFileGid = PUBLIC_DISK_GROUP; + fileWritten.size = archiveFileSize; + fileWritten.checksumBlob.insert(checksum::ADLER32, "1357"); + fileWritten.storageClassName = m_storageClassDualCopy.name; + fileWritten.vid = tape1.vid; + fileWritten.fSeq = 1; + fileWritten.blockId = 1 * 100; + fileWritten.copyNb = 1; + fileWritten.tapeDrive = tapeDrive; + tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); + + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); + } + + // Write a second copy of file on tape + { + std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; + + std::ostringstream diskFileId; + diskFileId << 12345677; + + std::ostringstream diskFilePath; + diskFilePath << "/test/file1"; + + auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>(); + auto & fileWritten = *fileWrittenUP; + fileWritten.archiveFileId = 1; + fileWritten.diskInstance = diskInstance; + fileWritten.diskFileId = diskFileId.str(); + fileWritten.diskFilePath = diskFilePath.str(); + fileWritten.diskFileOwnerUid = PUBLIC_DISK_USER; + fileWritten.diskFileGid = PUBLIC_DISK_GROUP; + fileWritten.size = archiveFileSize; + fileWritten.checksumBlob.insert(checksum::ADLER32, "1357"); + fileWritten.storageClassName = m_storageClassDualCopy.name; + fileWritten.vid = tape2.vid; + fileWritten.fSeq = 1; + fileWritten.blockId = 1 * 100; + fileWritten.copyNb = 2; + fileWritten.tapeDrive = tapeDrive; + tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); + + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); + } + { + //Assert both copies written + auto archiveFile = m_catalogue->getArchiveFileById(1); + ASSERT_EQ(2, archiveFile.tapeFiles.size()); + } + + { + //delete copy of file on tape1 + m_catalogue->deleteTapeFileCopy(tape1.vid, "BC614D", diskInstance, reason); + auto archiveFile = m_catalogue->getArchiveFileById(1); + ASSERT_EQ(1, archiveFile.tapeFiles.size()); + } + + // Rewrite deleted copy of file on tape + { + std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; + + std::ostringstream diskFileId; + diskFileId << 12345677; + + std::ostringstream diskFilePath; + diskFilePath << "/test/file1"; + + auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>(); + auto & fileWritten = *fileWrittenUP; + fileWritten.archiveFileId = 1; + fileWritten.diskInstance = diskInstance; + fileWritten.diskFileId = diskFileId.str(); + fileWritten.diskFilePath = diskFilePath.str(); + fileWritten.diskFileOwnerUid = PUBLIC_DISK_USER; + fileWritten.diskFileGid = PUBLIC_DISK_GROUP; + fileWritten.size = archiveFileSize; + fileWritten.checksumBlob.insert(checksum::ADLER32, "1357"); + fileWritten.storageClassName = m_storageClassDualCopy.name; + fileWritten.vid = tape1.vid; + fileWritten.fSeq = 2; + fileWritten.blockId = 1 * 100; + fileWritten.copyNb = 1; + fileWritten.tapeDrive = tapeDrive; + tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); + + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); + } + + { + //restore copy of file on tape1 + catalogue::RecycleTapeFileSearchCriteria searchCriteria; + searchCriteria.archiveFileId = 1; + searchCriteria.vid = tape1.vid; + + ASSERT_THROW(m_catalogue->restoreFilesInRecycleLog(searchCriteria), catalogue::UserSpecifiedExistingDeletedFileCopy); + auto archiveFile = m_catalogue->getArchiveFileById(1); + //assert only two copies present + ASSERT_EQ(2, archiveFile.tapeFiles.size()); + + //assert recycle log still contains deleted copy + auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(); + ASSERT_TRUE(fileRecycleLogItor.hasMore()); + + } +} + +TEST_P(cta_catalogue_CatalogueTest, RestoreVariousDeletedTapeFileCopies) { + using namespace cta; + + const bool logicalLibraryIsDisabled= false; + const std::string tapePoolName1 = "tape_pool_name_1"; + const std::string tapePoolName2 = "tape_pool_name_2"; + const std::string tapePoolName3 = "tape_pool_name_3"; + const uint64_t nbPartialTapes = 1; + const bool isEncrypted = true; + const cta::optional<std::string> supply("value for the supply pool mechanism"); + const std::string diskInstance = "disk_instance"; + const std::string tapeDrive = "tape_drive"; + const std::string reason = "reason"; + + m_catalogue->createMediaType(m_admin, m_mediaType); + m_catalogue->createLogicalLibrary(m_admin, m_tape1.logicalLibraryName, logicalLibraryIsDisabled, "Create logical library"); + m_catalogue->createVirtualOrganization(m_admin, m_vo); + m_catalogue->createTapePool(m_admin, tapePoolName1, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool"); + m_catalogue->createTapePool(m_admin, tapePoolName2, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool"); + m_catalogue->createTapePool(m_admin, tapePoolName3, m_vo.name, nbPartialTapes, isEncrypted, supply, "Create tape pool"); + m_catalogue->createStorageClass(m_admin, m_storageClassTripleCopy); + + auto tape1 = m_tape1; + auto tape2 = m_tape2; + auto tape3 = m_tape3; + tape1.tapePoolName = tapePoolName1; + tape2.tapePoolName = tapePoolName2; + tape3.tapePoolName = tapePoolName3; + + m_catalogue->createTape(m_admin, tape1); + m_catalogue->createTape(m_admin, tape2); + m_catalogue->createTape(m_admin, tape3); + + ASSERT_FALSE(m_catalogue->getArchiveFilesItor().hasMore()); + const uint64_t archiveFileSize = 2 * 1000 * 1000 * 1000; + + + // Write a file on tape + { + std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; + + std::ostringstream diskFileId; + diskFileId << 12345677; + + std::ostringstream diskFilePath; + diskFilePath << "/test/file1"; + + auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>(); + auto & fileWritten = *fileWrittenUP; + fileWritten.archiveFileId = 1; + fileWritten.diskInstance = diskInstance; + fileWritten.diskFileId = diskFileId.str(); + fileWritten.diskFilePath = diskFilePath.str(); + fileWritten.diskFileOwnerUid = PUBLIC_DISK_USER; + fileWritten.diskFileGid = PUBLIC_DISK_GROUP; + fileWritten.size = archiveFileSize; + fileWritten.checksumBlob.insert(checksum::ADLER32, "1357"); + fileWritten.storageClassName = m_storageClassTripleCopy.name; + fileWritten.vid = tape1.vid; + fileWritten.fSeq = 1; + fileWritten.blockId = 1 * 100; + fileWritten.copyNb = 1; + fileWritten.tapeDrive = tapeDrive; + tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); + + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); + } + + // Write a second copy of file on tape + { + std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; + + std::ostringstream diskFileId; + diskFileId << 12345677; + + std::ostringstream diskFilePath; + diskFilePath << "/test/file1"; + + auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>(); + auto & fileWritten = *fileWrittenUP; + fileWritten.archiveFileId = 1; + fileWritten.diskInstance = diskInstance; + fileWritten.diskFileId = diskFileId.str(); + fileWritten.diskFilePath = diskFilePath.str(); + fileWritten.diskFileOwnerUid = PUBLIC_DISK_USER; + fileWritten.diskFileGid = PUBLIC_DISK_GROUP; + fileWritten.size = archiveFileSize; + fileWritten.checksumBlob.insert(checksum::ADLER32, "1357"); + fileWritten.storageClassName = m_storageClassTripleCopy.name; + fileWritten.vid = tape2.vid; + fileWritten.fSeq = 1; + fileWritten.blockId = 1 * 100; + fileWritten.copyNb = 2; + fileWritten.tapeDrive = tapeDrive; + tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); + + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); + } + + // Write a third copy of file on tape + { + std::set<catalogue::TapeItemWrittenPointer> tapeFilesWrittenCopy1; + + std::ostringstream diskFileId; + diskFileId << 12345677; + + std::ostringstream diskFilePath; + diskFilePath << "/test/file1"; + + auto fileWrittenUP=cta::make_unique<cta::catalogue::TapeFileWritten>(); + auto & fileWritten = *fileWrittenUP; + fileWritten.archiveFileId = 1; + fileWritten.diskInstance = diskInstance; + fileWritten.diskFileId = diskFileId.str(); + fileWritten.diskFilePath = diskFilePath.str(); + fileWritten.diskFileOwnerUid = PUBLIC_DISK_USER; + fileWritten.diskFileGid = PUBLIC_DISK_GROUP; + fileWritten.size = archiveFileSize; + fileWritten.checksumBlob.insert(checksum::ADLER32, "1357"); + fileWritten.storageClassName = m_storageClassTripleCopy.name; + fileWritten.vid = tape3.vid; + fileWritten.fSeq = 1; + fileWritten.blockId = 1 * 100; + fileWritten.copyNb = 3; + fileWritten.tapeDrive = tapeDrive; + tapeFilesWrittenCopy1.emplace(fileWrittenUP.release()); + + m_catalogue->filesWrittenToTape(tapeFilesWrittenCopy1); + } + { + //Assert all copies written + auto archiveFile = m_catalogue->getArchiveFileById(1); + ASSERT_EQ(3, archiveFile.tapeFiles.size()); + } + + { + //delete copy of file on tape1 + m_catalogue->deleteTapeFileCopy(tape1.vid, "BC614D", diskInstance, reason); + auto archiveFile = m_catalogue->getArchiveFileById(1); + ASSERT_EQ(2, archiveFile.tapeFiles.size()); + } + + { + //delete copy of file on tape2 + m_catalogue->deleteTapeFileCopy(tape2.vid, "BC614D", diskInstance, reason); + auto archiveFile = m_catalogue->getArchiveFileById(1); + ASSERT_EQ(1, archiveFile.tapeFiles.size()); + } + + + { + //restore all deleted copies + catalogue::RecycleTapeFileSearchCriteria searchCriteria; + searchCriteria.archiveFileId = 1; + + m_catalogue->restoreFilesInRecycleLog(searchCriteria); + auto archiveFile = m_catalogue->getArchiveFileById(1); + //assert only two copies present + ASSERT_EQ(3, archiveFile.tapeFiles.size()); + + //assert recycle log still contains deleted copy + auto fileRecycleLogItor = m_catalogue->getFileRecycleLogItor(); + ASSERT_FALSE(fileRecycleLogItor.hasMore()); + + } +} + + } // namespace unitTests diff --git a/catalogue/CatalogueTest.hpp b/catalogue/CatalogueTest.hpp index b15bb24f6b9e6a3f3c22bec44c2997921388acfa..d556ad63aa0688e09d1bec7bff67fb21d4fc6ab2 100644 --- a/catalogue/CatalogueTest.hpp +++ b/catalogue/CatalogueTest.hpp @@ -46,9 +46,11 @@ protected: const cta::common::dataStructures::StorageClass m_storageClassSingleCopy; const cta::common::dataStructures::StorageClass m_anotherStorageClass; const cta::common::dataStructures::StorageClass m_storageClassDualCopy; + const cta::common::dataStructures::StorageClass m_storageClassTripleCopy; const cta::catalogue::MediaType m_mediaType; const cta::catalogue::CreateTapeAttributes m_tape1; const cta::catalogue::CreateTapeAttributes m_tape2; + const cta::catalogue::CreateTapeAttributes m_tape3; virtual void SetUp(); diff --git a/catalogue/DummyCatalogue.hpp b/catalogue/DummyCatalogue.hpp index 05a0a1a357e44bfcb854be426f077b8ecb0c9e27..dae4b7201c4946cf1f15c301820a2919047b436c 100644 --- a/catalogue/DummyCatalogue.hpp +++ b/catalogue/DummyCatalogue.hpp @@ -85,6 +85,7 @@ public: common::dataStructures::ArchiveFile getArchiveFileById(const uint64_t id) const override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } ArchiveFileItor getArchiveFilesItor(const TapeFileSearchCriteria& searchCriteria) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } FileRecycleLogItor getFileRecycleLogItor(const RecycleTapeFileSearchCriteria & searchCriteria) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } + void restoreFilesInRecycleLog(const RecycleTapeFileSearchCriteria & searchCriteria) { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void deleteFileFromRecycleBin(const uint64_t archiveFileId, log::LogContext &lc) {throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented");} void deleteFilesFromRecycleLog(const std::string & vid, log::LogContext & lc) {throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented");} void createTapeDrive(const common::dataStructures::TapeDrive &tapeDrive) {throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented");} @@ -102,6 +103,7 @@ public: std::list<common::dataStructures::RequesterGroupMountRule> getRequesterGroupMountRules() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } std::list<common::dataStructures::RequesterMountRule> getRequesterMountRules() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } std::list<common::dataStructures::StorageClass> getStorageClasses() const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } + common::dataStructures::StorageClass getStorageClass(const std::string &name) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } common::dataStructures::ArchiveFileSummary getTapeFileSummary(const TapeFileSearchCriteria& searchCriteria) const { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void deleteTapeFileCopy(const std::string &vid, const uint64_t archiveFileId, const std::string &reason) override {throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented");} void deleteTapeFileCopy(const std::string &vid, const std::string &diskFileId, const std::string &diskInstanceName, const std::string &reason) override {throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented");} @@ -122,6 +124,7 @@ public: void modifyVirtualOrganizationName(const common::dataStructures::SecurityIdentity &admin, const std::string ¤tVoName, const std::string &newVoName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyVirtualOrganizationReadMaxDrives(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t readMaxDrives) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyVirtualOrganizationWriteMaxDrives(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t writeMaxDrives) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } + void modifyVirtualOrganizationMaxFileSize(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t maxFileSize) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyVirtualOrganizationComment(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const std::string &comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyArchiveRouteComment(const common::dataStructures::SecurityIdentity& admin, const std::string& storageClassName, const uint32_t copyNb, const std::string& comment) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } void modifyArchiveRouteTapePoolName(const common::dataStructures::SecurityIdentity& admin, const std::string& storageClassName, const uint32_t copyNb, const std::string& tapePoolName) override { throw exception::Exception(std::string("In ")+__PRETTY_FUNCTION__+": not implemented"); } diff --git a/catalogue/MysqlCatalogue.cpp b/catalogue/MysqlCatalogue.cpp index f9c184f415ac7979b9c60bae07289dbd074117c3..f8f450b0064fdf6a635e4bc723e48e32fd8c6b1d 100644 --- a/catalogue/MysqlCatalogue.cpp +++ b/catalogue/MysqlCatalogue.cpp @@ -820,5 +820,95 @@ void MysqlCatalogue::copyTapeFileToFileRecyleLogAndDelete(rdbms::Conn & conn, co } } +//------------------------------------------------------------------------------ +// restoreFileCopiesInRecycleLog +//------------------------------------------------------------------------------ +void MysqlCatalogue::restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) { +try { + utils::Timer t; + log::TimingList tl; + + //put fileRecycleLogs in std::list so we can release the underlying fileRecycleLogItor database connection + //otherwise we are using two conns when calling getArchiveFilesItor + std::list<common::dataStructures::FileRecycleLog> fileRecycleLogList; + while (fileRecycleLogItor.hasMore()) { + auto fileRecycleLog = fileRecycleLogItor.next(); + fileRecycleLogList.push_back(fileRecycleLog); + } + + //We currently do all file copies restoring in a single transaction + conn.executeNonQuery("START TRANSACTION"); + for (auto &fileRecycleLog: fileRecycleLogList) { + TapeFileSearchCriteria searchCriteria; + searchCriteria.archiveFileId = fileRecycleLog.archiveFileId; + searchCriteria.diskInstance = fileRecycleLog.diskInstanceName; + searchCriteria.diskFileIds = std::vector<std::string>(); + searchCriteria.diskFileIds.value().push_back(fileRecycleLog.diskFileId); + + auto itor = getArchiveFilesItor(conn, searchCriteria); + if (itor.hasMore()) { + //only restore file copies, do nothing if file has been completely deleted in CTA + cta::common::dataStructures::ArchiveFile archiveFile = itor.next(); + if (archiveFile.tapeFiles.find(fileRecycleLog.copyNb) != archiveFile.tapeFiles.end()) { + //copy with same copy_nb exists, cannot restore + UserSpecifiedExistingDeletedFileCopy ex; + ex.getMessage() << "Cannot restore file copy with archiveFileId " << std::to_string(fileRecycleLog.archiveFileId) + << " and copy_nb " << std::to_string(fileRecycleLog.copyNb) << " because a tapefile with same archiveFileId and copy_nb already exists"; + throw ex; + } + restoreFileCopyInRecycleLog(conn, fileRecycleLog, lc); + } + } + conn.commit(); + + log::ScopedParamContainer spc(lc); + tl.insertAndReset("commitTime",t); + tl.addToLog(spc); + lc.log(log::INFO,"In MysqlCatalogue::restoreFileCopiesInRecycleLog: all file copies successfully restored."); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + +//------------------------------------------------------------------------------ +// restoreFileCopyInRecycleLog +//------------------------------------------------------------------------------ +void MysqlCatalogue::restoreFileCopyInRecycleLog(rdbms::Conn & conn, const common::dataStructures::FileRecycleLog &fileRecycleLog, log::LogContext & lc) { + try { + utils::Timer t; + log::TimingList tl; + cta::common::dataStructures::TapeFile tapeFile; + tapeFile.vid = fileRecycleLog.vid; + tapeFile.fSeq = fileRecycleLog.fSeq; + tapeFile.copyNb = fileRecycleLog.copyNb; + tapeFile.blockId = fileRecycleLog.blockId; + tapeFile.fileSize = fileRecycleLog.sizeInBytes; + tapeFile.creationTime = fileRecycleLog.tapeFileCreationTime; + + insertTapeFile(conn, tapeFile, fileRecycleLog.archiveFileId); + tl.insertAndReset("insertTapeFileTime",t); + + deleteTapeFileCopyFromRecycleBin(conn, fileRecycleLog); + tl.insertAndReset("deleteTapeFileCopyFromRecycleBinTime",t); + + log::ScopedParamContainer spc(lc); + spc.add("vid", tapeFile.vid); + spc.add("archiveFileId", fileRecycleLog.archiveFileId); + spc.add("fSeq", tapeFile.fSeq); + spc.add("copyNb", tapeFile.copyNb); + spc.add("fileSize", tapeFile.fileSize); + tl.addToLog(spc); + lc.log(log::INFO,"In MysqlCatalogue::restoreFileCopyInRecycleLog: File restored from the recycle log."); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + } // namespace catalogue } // namespace cta diff --git a/catalogue/MysqlCatalogue.hpp b/catalogue/MysqlCatalogue.hpp index 74ed0b0f5efd921bb7e425d520b7ea0f8af0ab55..75df118fd39fbd9d4da9adf8d5f62617771f7a5b 100644 --- a/catalogue/MysqlCatalogue.hpp +++ b/catalogue/MysqlCatalogue.hpp @@ -219,6 +219,22 @@ protected: void copyTapeFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const cta::common::dataStructures::ArchiveFile &file, const std::string &reason, log::LogContext & lc) override; + /** + * Copy the files in fileRecycleLogItor to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entries + * @param conn the database connection + * @param fileRecycleLogItor the collection of fileRecycleLogs we want to restore + * @param lc the log context + */ + void restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) override; + + /** + * Copy the fileRecycleLog to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entry + * @param conn the database connection + * @param fileRecycleLog the fileRecycleLog we want to restore + * @param lc the log context + */ + void restoreFileCopyInRecycleLog(rdbms::Conn & conn, const common::dataStructures::FileRecycleLog &fileRecycleLogItor, log::LogContext & lc); + private: diff --git a/catalogue/OracleCatalogue.cpp b/catalogue/OracleCatalogue.cpp index e15b23d3d0f994cb26bc57a0c5f3364ddd859e56..98717eee30bc6ff9500e5670629ec3c5d6cd9c52 100644 --- a/catalogue/OracleCatalogue.cpp +++ b/catalogue/OracleCatalogue.cpp @@ -1149,6 +1149,99 @@ void OracleCatalogue::copyTapeFileToFileRecyleLogAndDelete(rdbms::Conn & conn, c } } +//------------------------------------------------------------------------------ +// restoreFileCopiesInRecycleLog +//------------------------------------------------------------------------------ +void OracleCatalogue::restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) { +try { + utils::Timer t; + log::TimingList tl; + + //put fileRecycleLogs in std::list so we can release the underlying fileRecycleLogItor database connection + //otherwise we are using two conns when calling getArchiveFilesItor + std::list<common::dataStructures::FileRecycleLog> fileRecycleLogList; + while (fileRecycleLogItor.hasMore()) { + auto fileRecycleLog = fileRecycleLogItor.next(); + fileRecycleLogList.push_back(fileRecycleLog); + } + + //We currently do all file copies restoring in a single transaction + conn.setAutocommitMode(rdbms::AutocommitMode::AUTOCOMMIT_OFF); + for (auto &fileRecycleLog: fileRecycleLogList) { + TapeFileSearchCriteria searchCriteria; + searchCriteria.archiveFileId = fileRecycleLog.archiveFileId; + searchCriteria.diskInstance = fileRecycleLog.diskInstanceName; + searchCriteria.diskFileIds = std::vector<std::string>(); + searchCriteria.diskFileIds.value().push_back(fileRecycleLog.diskFileId); + + auto itor = getArchiveFilesItor(conn, searchCriteria); + if (itor.hasMore()) { + //only restore file copies, do nothing if file has been completely deleted in CTA + cta::common::dataStructures::ArchiveFile archiveFile = itor.next(); + if (archiveFile.tapeFiles.find(fileRecycleLog.copyNb) != archiveFile.tapeFiles.end()) { + //copy with same copy_nb exists, cannot restore + UserSpecifiedExistingDeletedFileCopy ex; + ex.getMessage() << "Cannot restore file copy with archiveFileId " << std::to_string(fileRecycleLog.archiveFileId) + << " and copy_nb " << std::to_string(fileRecycleLog.copyNb) << " because a tapefile with same archiveFileId and copy_nb already exists"; + throw ex; + } + restoreFileCopyInRecycleLog(conn, fileRecycleLog, lc); + } + } + conn.setAutocommitMode(rdbms::AutocommitMode::AUTOCOMMIT_ON); + conn.commit(); + + log::ScopedParamContainer spc(lc); + tl.insertAndReset("commitTime",t); + tl.addToLog(spc); + lc.log(log::INFO,"In OracleCatalogue::restoreFileCopiesInRecycleLog: all file copies successfully restored."); + + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + +//------------------------------------------------------------------------------ +// restoreFileCopyInRecycleLog +//------------------------------------------------------------------------------ +void OracleCatalogue::restoreFileCopyInRecycleLog(rdbms::Conn & conn, const common::dataStructures::FileRecycleLog &fileRecycleLog, log::LogContext & lc) { + try { + utils::Timer t; + log::TimingList tl; + cta::common::dataStructures::TapeFile tapeFile; + tapeFile.vid = fileRecycleLog.vid; + tapeFile.fSeq = fileRecycleLog.fSeq; + tapeFile.copyNb = fileRecycleLog.copyNb; + tapeFile.blockId = fileRecycleLog.blockId; + tapeFile.fileSize = fileRecycleLog.sizeInBytes; + tapeFile.creationTime = fileRecycleLog.tapeFileCreationTime; + + insertTapeFile(conn, tapeFile, fileRecycleLog.archiveFileId); + tl.insertAndReset("insertTapeFileTime",t); + + deleteTapeFileCopyFromRecycleBin(conn, fileRecycleLog); + tl.insertAndReset("deleteTapeFileCopyFromRecycleBinTime",t); + + log::ScopedParamContainer spc(lc); + spc.add("vid", tapeFile.vid); + spc.add("archiveFileId", fileRecycleLog.archiveFileId); + spc.add("fSeq", tapeFile.fSeq); + spc.add("copyNb", tapeFile.copyNb); + spc.add("fileSize", tapeFile.fileSize); + tl.addToLog(spc); + lc.log(log::INFO,"In OracleCatalogue::restoreFileCopyInRecycleLog: File restored from the recycle log."); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + + } // namespace catalogue } // namespace cta diff --git a/catalogue/OracleCatalogue.hpp b/catalogue/OracleCatalogue.hpp index f0c05cf0176a027691eb1eb17f90958f59a36719..172cb55e0fe1f8502355ec607ce271689a236162 100644 --- a/catalogue/OracleCatalogue.hpp +++ b/catalogue/OracleCatalogue.hpp @@ -262,6 +262,22 @@ private: void copyTapeFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const cta::common::dataStructures::ArchiveFile &file, const std::string &reason, log::LogContext & lc) override; + /** + * Copy the files in fileRecycleLogItor to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entries + * @param conn the database connection + * @param fileRecycleLogItor the collection of fileRecycleLogs we want to restore + * @param lc the log context + */ + void restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) override; + + /** + * Copy the fileRecycleLog to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entry + * @param conn the database connection + * @param fileRecycleLog the fileRecycleLog we want to restore + * @param lc the log context + */ + void restoreFileCopyInRecycleLog(rdbms::Conn & conn, const common::dataStructures::FileRecycleLog &fileRecycleLogItor, log::LogContext & lc); + /** * The size and checksum of a file. */ diff --git a/catalogue/PostgresCatalogue.cpp b/catalogue/PostgresCatalogue.cpp index 8967dd6901303673dbb3df209f735744e46e8534..7b06ba81b33c23e5aa601ed3575d3dc467888885 100644 --- a/catalogue/PostgresCatalogue.cpp +++ b/catalogue/PostgresCatalogue.cpp @@ -1109,5 +1109,96 @@ void PostgresCatalogue::copyTapeFileToFileRecyleLogAndDelete(rdbms::Conn & conn, } } +//------------------------------------------------------------------------------ +// restoreFileCopiesInRecycleLog +//------------------------------------------------------------------------------ +void PostgresCatalogue::restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) { +try { + utils::Timer t; + log::TimingList tl; + + //put fileRecycleLogs in std::list so we can release the underlying fileRecycleLogItor database connection + //otherwise we are using two conns when calling getArchiveFilesItor + std::list<common::dataStructures::FileRecycleLog> fileRecycleLogList; + while (fileRecycleLogItor.hasMore()) { + auto fileRecycleLog = fileRecycleLogItor.next(); + fileRecycleLogList.push_back(fileRecycleLog); + } + + //We currently do all file copies restoring in a single transaction + conn.executeNonQuery("BEGIN"); + for (auto &fileRecycleLog: fileRecycleLogList) { + TapeFileSearchCriteria searchCriteria; + searchCriteria.archiveFileId = fileRecycleLog.archiveFileId; + searchCriteria.diskInstance = fileRecycleLog.diskInstanceName; + searchCriteria.diskFileIds = std::vector<std::string>(); + searchCriteria.diskFileIds.value().push_back(fileRecycleLog.diskFileId); + + auto itor = getArchiveFilesItor(conn, searchCriteria); + if (itor.hasMore()) { + //only restore file copies, do nothing if file has been completely deleted in CTA + cta::common::dataStructures::ArchiveFile archiveFile = itor.next(); + if (archiveFile.tapeFiles.find(fileRecycleLog.copyNb) != archiveFile.tapeFiles.end()) { + //copy with same copy_nb exists, cannot restore + UserSpecifiedExistingDeletedFileCopy ex; + ex.getMessage() << "Cannot restore file copy with archiveFileId " << std::to_string(fileRecycleLog.archiveFileId) + << " and copy_nb " << std::to_string(fileRecycleLog.copyNb) << " because a tapefile with same archiveFileId and copy_nb already exists"; + throw ex; + } + restoreFileCopyInRecycleLog(conn, fileRecycleLog, lc); + } + } + conn.commit(); + + log::ScopedParamContainer spc(lc); + tl.insertAndReset("commitTime",t); + tl.addToLog(spc); + lc.log(log::INFO,"In PostgresCatalogue::restoreFileCopiesInRecycleLog: all file copies successfully restored."); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + +//------------------------------------------------------------------------------ +// restoreFileCopyInRecycleLog +//------------------------------------------------------------------------------ +void PostgresCatalogue::restoreFileCopyInRecycleLog(rdbms::Conn & conn, const common::dataStructures::FileRecycleLog &fileRecycleLog, log::LogContext & lc) { + try { + utils::Timer t; + log::TimingList tl; + cta::common::dataStructures::TapeFile tapeFile; + tapeFile.vid = fileRecycleLog.vid; + tapeFile.fSeq = fileRecycleLog.fSeq; + tapeFile.copyNb = fileRecycleLog.copyNb; + tapeFile.blockId = fileRecycleLog.blockId; + tapeFile.fileSize = fileRecycleLog.sizeInBytes; + tapeFile.creationTime = fileRecycleLog.tapeFileCreationTime; + + insertTapeFile(conn, tapeFile, fileRecycleLog.archiveFileId); + tl.insertAndReset("insertTapeFileTime",t); + + deleteTapeFileCopyFromRecycleBin(conn, fileRecycleLog); + tl.insertAndReset("deleteTapeFileCopyFromRecycleBinTime",t); + + log::ScopedParamContainer spc(lc); + spc.add("vid", tapeFile.vid); + spc.add("archiveFileId", fileRecycleLog.archiveFileId); + spc.add("fSeq", tapeFile.fSeq); + spc.add("copyNb", tapeFile.copyNb); + spc.add("fileSize", tapeFile.fileSize); + tl.addToLog(spc); + lc.log(log::INFO,"In PostgresCatalogue::restoreFileCopyInRecycleLog: File restored from the recycle log."); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + + } // namespace catalogue } // namespace cta diff --git a/catalogue/PostgresCatalogue.hpp b/catalogue/PostgresCatalogue.hpp index 90bacb1e28ad5833af7c823b934e3423ed2a1cfe..4d50cef0d35d6fcc8062de55f08719d7b0c11ed2 100644 --- a/catalogue/PostgresCatalogue.hpp +++ b/catalogue/PostgresCatalogue.hpp @@ -296,6 +296,22 @@ private: void copyTapeFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const cta::common::dataStructures::ArchiveFile &file, const std::string &reason, log::LogContext & lc) override; + /** + * Copy the files in fileRecycleLogItor to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entries + * @param conn the database connection + * @param fileRecycleLogItor the collection of fileRecycleLogs we want to restore + * @param lc the log context + */ + void restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) override; + + /** + * Copy the fileRecycleLog to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entry + * @param conn the database connection + * @param fileRecycleLog the fileRecycleLog we want to restore + * @param lc the log context + */ + void restoreFileCopyInRecycleLog(rdbms::Conn & conn, const common::dataStructures::FileRecycleLog &fileRecycleLogItor, log::LogContext & lc); + }; // class PostgresCatalogue } // namespace catalogue diff --git a/catalogue/RdbmsCatalogue.cpp b/catalogue/RdbmsCatalogue.cpp index 1f3a640fe6b985a86120af6f55b48df91e1675bc..afec1c7a2bfc6116fc74ddd48593c282afa38d89 100644 --- a/catalogue/RdbmsCatalogue.cpp +++ b/catalogue/RdbmsCatalogue.cpp @@ -332,6 +332,7 @@ void RdbmsCatalogue::createVirtualOrganization(const common::dataStructures::Sec "READ_MAX_DRIVES," "WRITE_MAX_DRIVES," + "MAX_FILE_SIZE," "USER_COMMENT," @@ -347,6 +348,7 @@ void RdbmsCatalogue::createVirtualOrganization(const common::dataStructures::Sec ":VIRTUAL_ORGANIZATION_NAME," ":READ_MAX_DRIVES," ":WRITE_MAX_DRIVES," + ":MAX_FILE_SIZE," ":USER_COMMENT," @@ -364,6 +366,7 @@ void RdbmsCatalogue::createVirtualOrganization(const common::dataStructures::Sec stmt.bindUint64(":READ_MAX_DRIVES",vo.readMaxDrives); stmt.bindUint64(":WRITE_MAX_DRIVES",vo.writeMaxDrives); + stmt.bindUint64(":MAX_FILE_SIZE", vo.maxFileSize); stmt.bindString(":USER_COMMENT", vo.comment); @@ -439,6 +442,7 @@ std::list<common::dataStructures::VirtualOrganization> RdbmsCatalogue::getVirtua "READ_MAX_DRIVES AS READ_MAX_DRIVES," "WRITE_MAX_DRIVES AS WRITE_MAX_DRIVES," + "MAX_FILE_SIZE AS MAX_FILE_SIZE," "USER_COMMENT AS USER_COMMENT," @@ -463,6 +467,7 @@ std::list<common::dataStructures::VirtualOrganization> RdbmsCatalogue::getVirtua virtualOrganization.readMaxDrives = rset.columnUint64("READ_MAX_DRIVES"); virtualOrganization.writeMaxDrives = rset.columnUint64("WRITE_MAX_DRIVES"); + virtualOrganization.maxFileSize = rset.columnUint64("MAX_FILE_SIZE"); virtualOrganization.comment = rset.columnString("USER_COMMENT"); virtualOrganization.creationLog.username = rset.columnString("CREATION_LOG_USER_NAME"); virtualOrganization.creationLog.host = rset.columnString("CREATION_LOG_HOST_NAME"); @@ -509,7 +514,8 @@ common::dataStructures::VirtualOrganization RdbmsCatalogue::getVirtualOrganizati "VIRTUAL_ORGANIZATION.READ_MAX_DRIVES AS READ_MAX_DRIVES," "VIRTUAL_ORGANIZATION.WRITE_MAX_DRIVES AS WRITE_MAX_DRIVES," - + "VIRTUAL_ORGANIZATION.MAX_FILE_SIZE AS MAX_FILE_SIZE," + "VIRTUAL_ORGANIZATION.USER_COMMENT AS USER_COMMENT," "VIRTUAL_ORGANIZATION.CREATION_LOG_USER_NAME AS CREATION_LOG_USER_NAME," @@ -538,6 +544,7 @@ common::dataStructures::VirtualOrganization RdbmsCatalogue::getVirtualOrganizati virtualOrganization.name = rset.columnString("VIRTUAL_ORGANIZATION_NAME"); virtualOrganization.readMaxDrives = rset.columnUint64("READ_MAX_DRIVES"); virtualOrganization.writeMaxDrives = rset.columnUint64("WRITE_MAX_DRIVES"); + virtualOrganization.maxFileSize = rset.columnUint64("MAX_FILE_SIZE"); virtualOrganization.comment = rset.columnString("USER_COMMENT"); virtualOrganization.creationLog.username = rset.columnString("CREATION_LOG_USER_NAME"); virtualOrganization.creationLog.host = rset.columnString("CREATION_LOG_HOST_NAME"); @@ -689,6 +696,42 @@ void RdbmsCatalogue::modifyVirtualOrganizationWriteMaxDrives(const common::dataS } } +void RdbmsCatalogue::modifyVirtualOrganizationMaxFileSize(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t maxFileSize){ + try { + const time_t now = time(nullptr); + const char *const sql = + "UPDATE VIRTUAL_ORGANIZATION SET " + "MAX_FILE_SIZE = :MAX_FILE_SIZE," + "LAST_UPDATE_USER_NAME = :LAST_UPDATE_USER_NAME," + "LAST_UPDATE_HOST_NAME = :LAST_UPDATE_HOST_NAME," + "LAST_UPDATE_TIME = :LAST_UPDATE_TIME " + "WHERE " + "VIRTUAL_ORGANIZATION_NAME = :VIRTUAL_ORGANIZATION_NAME"; + auto conn = m_connPool.getConn(); + + auto stmt = conn.createStmt(sql); + stmt.bindUint64(":MAX_FILE_SIZE", maxFileSize); + stmt.bindString(":LAST_UPDATE_USER_NAME", admin.username); + stmt.bindString(":LAST_UPDATE_HOST_NAME", admin.host); + stmt.bindUint64(":LAST_UPDATE_TIME", now); + stmt.bindString(":VIRTUAL_ORGANIZATION_NAME", voName); + stmt.executeNonQuery(); + + if(0 == stmt.getNbAffectedRows()) { + throw exception::UserError(std::string("Cannot modify virtual organization : ") + voName + + " because it does not exist"); + } + + m_tapepoolVirtualOrganizationCache.invalidate(); + + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + void RdbmsCatalogue::modifyVirtualOrganizationComment(const common::dataStructures::SecurityIdentity& admin, const std::string& voName, const std::string& comment) { try { const time_t now = time(nullptr); @@ -1107,6 +1150,65 @@ std::list<common::dataStructures::StorageClass> RdbmsCatalogue::getStorageClasse } } +//------------------------------------------------------------------------------ +// getStorageClasses +//------------------------------------------------------------------------------ +common::dataStructures::StorageClass RdbmsCatalogue::getStorageClass(const std::string &name) const { + try { + const char *const sql = + "SELECT " + "STORAGE_CLASS_NAME AS STORAGE_CLASS_NAME," + "NB_COPIES AS NB_COPIES," + "VIRTUAL_ORGANIZATION.VIRTUAL_ORGANIZATION_NAME AS VIRTUAL_ORGANIZATION_NAME," + "VIRTUAL_ORGANIZATION.MAX_FILE_SIZE AS MAX_FILE_SIZE," + "STORAGE_CLASS.USER_COMMENT AS USER_COMMENT," + + "STORAGE_CLASS.CREATION_LOG_USER_NAME AS CREATION_LOG_USER_NAME," + "STORAGE_CLASS.CREATION_LOG_HOST_NAME AS CREATION_LOG_HOST_NAME," + "STORAGE_CLASS.CREATION_LOG_TIME AS CREATION_LOG_TIME," + + "STORAGE_CLASS.LAST_UPDATE_USER_NAME AS LAST_UPDATE_USER_NAME," + "STORAGE_CLASS.LAST_UPDATE_HOST_NAME AS LAST_UPDATE_HOST_NAME," + "STORAGE_CLASS.LAST_UPDATE_TIME AS LAST_UPDATE_TIME " + "FROM " + "STORAGE_CLASS " + "INNER JOIN " + "VIRTUAL_ORGANIZATION ON STORAGE_CLASS.VIRTUAL_ORGANIZATION_ID = VIRTUAL_ORGANIZATION.VIRTUAL_ORGANIZATION_ID " + "WHERE " + "STORAGE_CLASS_NAME = :STORAGE_CLASS_NAME"; + auto conn = m_connPool.getConn(); + auto stmt = conn.createStmt(sql); + stmt.bindString(":STORAGE_CLASS_NAME", name); + auto rset = stmt.executeQuery(); + if (rset.isEmpty()) { + throw exception::UserError(std::string("Cannot get storage class : ") + name + + " because it does not exist"); + } + rset.next(); + common::dataStructures::StorageClass storageClass; + + storageClass.name = rset.columnString("STORAGE_CLASS_NAME"); + storageClass.nbCopies = rset.columnUint64("NB_COPIES"); + storageClass.vo.name = rset.columnString("VIRTUAL_ORGANIZATION_NAME"); + storageClass.vo.maxFileSize = rset.columnUint64("MAX_FILE_SIZE"); + storageClass.comment = rset.columnString("USER_COMMENT"); + storageClass.creationLog.username = rset.columnString("CREATION_LOG_USER_NAME"); + storageClass.creationLog.host = rset.columnString("CREATION_LOG_HOST_NAME"); + storageClass.creationLog.time = rset.columnUint64("CREATION_LOG_TIME"); + storageClass.lastModificationLog.username = rset.columnString("LAST_UPDATE_USER_NAME"); + storageClass.lastModificationLog.host = rset.columnString("LAST_UPDATE_HOST_NAME"); + storageClass.lastModificationLog.time = rset.columnUint64("LAST_UPDATE_TIME"); + + return storageClass; + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + + //------------------------------------------------------------------------------ // modifyStorageClassNbCopies //------------------------------------------------------------------------------ @@ -6939,7 +7041,14 @@ void RdbmsCatalogue::insertArchiveFile(rdbms::Conn &conn, const ArchiveFileRowWi //------------------------------------------------------------------------------ void RdbmsCatalogue::checkTapeFileSearchCriteria(const TapeFileSearchCriteria &searchCriteria) const { auto conn = m_connPool.getConn(); + checkTapeFileSearchCriteria(conn, searchCriteria); + +} +//------------------------------------------------------------------------------ +// checkTapeFileSearchCriteria +//------------------------------------------------------------------------------ +void RdbmsCatalogue::checkTapeFileSearchCriteria(rdbms::Conn &conn, const TapeFileSearchCriteria &searchCriteria) const { if(searchCriteria.archiveFileId) { if(!archiveFileIdExists(conn, searchCriteria.archiveFileId.value())) { throw exception::UserError(std::string("Archive file with ID ") + @@ -6951,6 +7060,10 @@ void RdbmsCatalogue::checkTapeFileSearchCriteria(const TapeFileSearchCriteria &s throw exception::UserError(std::string("Disk file IDs are ambiguous without disk instance name")); } + if (searchCriteria.fSeq && !searchCriteria.vid) { + throw exception::UserError(std::string("fSeq makes no sense without vid")); + } + if(searchCriteria.vid) { if(!tapeExists(conn, searchCriteria.vid.value())) { throw exception::UserError(std::string("Tape ") + searchCriteria.vid.value() + " does not exist"); @@ -6966,8 +7079,8 @@ Catalogue::ArchiveFileItor RdbmsCatalogue::getArchiveFilesItor(const TapeFileSea checkTapeFileSearchCriteria(searchCriteria); // If this is the listing of the contents of a tape - if (!searchCriteria.archiveFileId && !searchCriteria.diskInstance && !searchCriteria.diskFileIds && - searchCriteria.vid) { + if (!searchCriteria.archiveFileId && !searchCriteria.diskInstance && !searchCriteria.diskFileIds && + !searchCriteria.fSeq && searchCriteria.vid) { return getTapeContentsItor(searchCriteria.vid.value()); } @@ -6986,6 +7099,33 @@ Catalogue::ArchiveFileItor RdbmsCatalogue::getArchiveFilesItor(const TapeFileSea } } +//------------------------------------------------------------------------------ +// getArchiveFilesItor +//------------------------------------------------------------------------------ +Catalogue::ArchiveFileItor RdbmsCatalogue::getArchiveFilesItor(rdbms::Conn &conn, const TapeFileSearchCriteria &searchCriteria) const { + + checkTapeFileSearchCriteria(conn, searchCriteria); + + // If this is the listing of the contents of a tape + if (!searchCriteria.archiveFileId && !searchCriteria.diskInstance && !searchCriteria.diskFileIds && + searchCriteria.vid) { + return getTapeContentsItor(searchCriteria.vid.value()); + } + + try { + auto archiveListingConn = m_archiveFileListingConnPool.getConn(); + const auto tempDiskFxidsTableName = createAndPopulateTempTableFxid(archiveListingConn, searchCriteria.diskFileIds); + // Pass ownership of the connection to the Iterator object + auto impl = new RdbmsCatalogueGetArchiveFilesItor(m_log, std::move(archiveListingConn), searchCriteria, tempDiskFxidsTableName); + return ArchiveFileItor(impl); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + //------------------------------------------------------------------------------ // getTapeContentsItor //------------------------------------------------------------------------------ @@ -7029,6 +7169,24 @@ Catalogue::FileRecycleLogItor RdbmsCatalogue::getFileRecycleLogItor(const Recycl } } + +//------------------------------------------------------------------------------ +// restoreFilesInRecycleLog +//------------------------------------------------------------------------------ +void RdbmsCatalogue::restoreFilesInRecycleLog(const RecycleTapeFileSearchCriteria & searchCriteria) { + try { + auto fileRecycleLogitor = getFileRecycleLogItor(searchCriteria); + auto conn = m_connPool.getConn(); + log::LogContext lc(m_log); + restoreFileCopiesInRecycleLog(conn, fileRecycleLogitor, lc); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + //------------------------------------------------------------------------------ // getFilesForRepack //------------------------------------------------------------------------------ @@ -9120,6 +9278,34 @@ void RdbmsCatalogue::deleteArchiveFileFromRecycleBin(rdbms::Conn& conn, const ui } } +//------------------------------------------------------------------------------ +// deleteTapeFileCopyFromRecycleBin +//------------------------------------------------------------------------------ +void RdbmsCatalogue::deleteTapeFileCopyFromRecycleBin(cta::rdbms::Conn & conn, const common::dataStructures::FileRecycleLog fileRecycleLog) { + try { + const char *const deleteTapeFilesSql = + "DELETE FROM " + "FILE_RECYCLE_LOG " + "WHERE FILE_RECYCLE_LOG.ARCHIVE_FILE_ID = :ARCHIVE_FILE_ID AND FILE_RECYCLE_LOG.VID = :VID AND " + "FILE_RECYCLE_LOG.FSEQ = :FSEQ AND FILE_RECYCLE_LOG.COPY_NB = :COPY_NB AND " + "FILE_RECYCLE_LOG.DISK_INSTANCE_NAME = :DISK_INSTANCE_NAME"; + + auto deleteTapeFilesStmt = conn.createStmt(deleteTapeFilesSql); + deleteTapeFilesStmt.bindUint64(":ARCHIVE_FILE_ID", fileRecycleLog.archiveFileId); + deleteTapeFilesStmt.bindString(":VID", fileRecycleLog.vid); + deleteTapeFilesStmt.bindUint64(":FSEQ", fileRecycleLog.fSeq); + deleteTapeFilesStmt.bindUint64(":COPY_NB", fileRecycleLog.copyNb); + deleteTapeFilesStmt.bindString(":DISK_INSTANCE_NAME", fileRecycleLog.diskInstanceName); + deleteTapeFilesStmt.executeNonQuery(); + + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + //------------------------------------------------------------------------------ // insertOldCopiesOfFilesIfAnyOnFileRecycleLog //------------------------------------------------------------------------------ diff --git a/catalogue/RdbmsCatalogue.hpp b/catalogue/RdbmsCatalogue.hpp index ecb4934b741285eba88d38f4d8ff9d59f8fa5660..5451b916cd6952ec3490f4ab38508f6d2c2a065b 100644 --- a/catalogue/RdbmsCatalogue.hpp +++ b/catalogue/RdbmsCatalogue.hpp @@ -282,6 +282,15 @@ public: * @param writeMaxDrives the new max number of allocated drives for write for the specified Virtual Organization */ void modifyVirtualOrganizationWriteMaxDrives(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t writeMaxDrives) override; + + /** + * Modifies the max file size for the specified Virtual Organization + * + * @param voName the VO name + * @param maxFileSize the new max file size for the specified Virtual Organization + */ + + void modifyVirtualOrganizationMaxFileSize(const common::dataStructures::SecurityIdentity &admin, const std::string &voName, const uint64_t maxFileSize) override; /** * Modifies the comment of the specified Virtual Organization * @@ -309,6 +318,9 @@ public: void deleteStorageClass(const std::string &storageClassName) override; std::list<common::dataStructures::StorageClass> getStorageClasses() const override; + common::dataStructures::StorageClass getStorageClass(const std::string &name) const override; + + void modifyStorageClassNbCopies(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const uint64_t nbCopies) override; void modifyStorageClassComment(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &comment) override; void modifyStorageClassVo(const common::dataStructures::SecurityIdentity &admin, const std::string &name, const std::string &vo) override; @@ -839,6 +851,15 @@ public: */ void checkTapeFileSearchCriteria(const TapeFileSearchCriteria &searchCriteria) const; + /** + * Throws a UserError exception if the specified searchCriteria is not valid + * due to a user error. + * + * @param conn The database connection. + * @param searchCriteria The search criteria. + */ + void checkTapeFileSearchCriteria(rdbms::Conn &conn, const TapeFileSearchCriteria &searchCriteria) const; + /** * Returns the specified archive files. Please note that the list of files * is ordered by archive file ID. @@ -848,6 +869,17 @@ public: */ ArchiveFileItor getArchiveFilesItor(const TapeFileSearchCriteria &searchCriteria) const override; + + /** + * Returns the specified archive files. Please note that the list of files + * is ordered by archive file ID. + * + * @param conn The database connection. + * @param searchCriteria The search criteria. + * @return The archive files. + */ + ArchiveFileItor getArchiveFilesItor(rdbms::Conn &conn, const TapeFileSearchCriteria &searchCriteria) const; + /** * Throws a UserError exception if the specified searchCriteria is not valid * due to a user error. @@ -864,6 +896,13 @@ public: */ FileRecycleLogItor getFileRecycleLogItor(const RecycleTapeFileSearchCriteria & searchCriteria) const override; + /** + * Restores the deleted files in the Recycle log that match the criteria passed + * + * @param searchCriteria The search criteria + */ + void restoreFilesInRecycleLog(const RecycleTapeFileSearchCriteria & searchCriteria) override; + /** * Returns the specified files in tape file sequence order. * @@ -1923,6 +1962,14 @@ protected: */ virtual void copyArchiveFileToFileRecyleLogAndDelete(rdbms::Conn & conn,const common::dataStructures::DeleteArchiveRequest &request, log::LogContext & lc) = 0; + /** + * Copy the fileRecycleLog to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entry + * @param conn the database connection + * @param fileRecycleLog the fileRecycleLog we want to restore + * @param lc the log context + */ + virtual void restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) = 0; + /** * Copies the ARCHIVE_FILE and TAPE_FILE entries to the recycle-bin tables * @param conn the database connection @@ -2037,6 +2084,8 @@ protected: */ void deleteTapeFilesFromRecycleBin(rdbms::Conn & conn, const uint64_t archiveFileId); + void deleteTapeFileCopyFromRecycleBin(cta::rdbms::Conn & conn, const common::dataStructures::FileRecycleLog fileRecycleLog); + /** * Delete the archive file from the ARCHIVE_FILE recycle-bin * @param conn the database connection diff --git a/catalogue/RdbmsCatalogueGetArchiveFilesItor.cpp b/catalogue/RdbmsCatalogueGetArchiveFilesItor.cpp index bef739104e2ebef88b109dd4426c7a32ad8a1acd..c7092b6e35cb6e58ab21e27f854710c58076431a 100644 --- a/catalogue/RdbmsCatalogueGetArchiveFilesItor.cpp +++ b/catalogue/RdbmsCatalogueGetArchiveFilesItor.cpp @@ -114,7 +114,8 @@ RdbmsCatalogueGetArchiveFilesItor::RdbmsCatalogueGetArchiveFilesItor( searchCriteria.archiveFileId || searchCriteria.diskInstance || searchCriteria.vid || - searchCriteria.diskFileIds; + searchCriteria.diskFileIds || + searchCriteria.fSeq; if(thereIsAtLeastOneSearchCriteria) { sql += " WHERE "; @@ -136,15 +137,24 @@ RdbmsCatalogueGetArchiveFilesItor::RdbmsCatalogueGetArchiveFilesItor( sql += "TAPE_FILE.VID = :VID"; addedAWhereConstraint = true; } + if (searchCriteria.fSeq) { + if(addedAWhereConstraint) sql += " AND "; + sql += "TAPE_FILE.FSEQ = :FSEQ"; + addedAWhereConstraint = true; + } if(searchCriteria.diskFileIds) { if(addedAWhereConstraint) sql += " AND "; sql += "ARCHIVE_FILE.DISK_FILE_ID IN (SELECT DISK_FILE_ID FROM " + tempDiskFxidsTableName + ")"; addedAWhereConstraint = true; } - // Order by FSEQ if we are listing the contents of a tape, else order by archive file ID + // Order by FSEQ if we are listing the contents of a tape, + // by DISK_FILE_ID if listing the contents of a DISK_INSTANCE + // else order by archive file ID if(searchCriteria.vid) { sql += " ORDER BY FSEQ"; + } else if (searchCriteria.diskInstance) { + sql += " ORDER BY DISK_FILE_ID"; } else { sql += " ORDER BY ARCHIVE_FILE_ID, COPY_NB"; } @@ -159,6 +169,11 @@ RdbmsCatalogueGetArchiveFilesItor::RdbmsCatalogueGetArchiveFilesItor( if(searchCriteria.vid) { m_stmt.bindString(":VID", searchCriteria.vid.value()); } + + if(searchCriteria.fSeq) { + m_stmt.bindUint64(":FSEQ", searchCriteria.fSeq.value()); + } + m_rset = m_stmt.executeQuery(); { log::LogContext lc(m_log); diff --git a/catalogue/SqliteCatalogue.cpp b/catalogue/SqliteCatalogue.cpp index f235c0279b3e224e75d9b0ea14512e7373091b3b..a3f3b98c7a30adc3823ca61e359d5b6b3729213d 100644 --- a/catalogue/SqliteCatalogue.cpp +++ b/catalogue/SqliteCatalogue.cpp @@ -685,5 +685,95 @@ void SqliteCatalogue::copyTapeFileToFileRecyleLogAndDelete(rdbms::Conn & conn, c } } +//------------------------------------------------------------------------------ +// restoreFileCopiesInRecycleLog +//------------------------------------------------------------------------------ +void SqliteCatalogue::restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) { +try { + utils::Timer t; + log::TimingList tl; + + //put fileRecycleLogs in std::list so we can release the underlying fileRecycleLogItor database connection + //otherwise we are using two conns when calling getArchiveFilesItor + std::list<common::dataStructures::FileRecycleLog> fileRecycleLogList; + while (fileRecycleLogItor.hasMore()) { + auto fileRecycleLog = fileRecycleLogItor.next(); + fileRecycleLogList.push_back(fileRecycleLog); + } + + //We currently do all file copy restoring in a single transaction + conn.executeNonQuery("BEGIN TRANSACTION"); + for (auto &fileRecycleLog: fileRecycleLogList) { + TapeFileSearchCriteria searchCriteria; + searchCriteria.archiveFileId = fileRecycleLog.archiveFileId; + searchCriteria.diskInstance = fileRecycleLog.diskInstanceName; + searchCriteria.diskFileIds = std::vector<std::string>(); + searchCriteria.diskFileIds.value().push_back(fileRecycleLog.diskFileId); + + auto itor = getArchiveFilesItor(conn, searchCriteria); + if (itor.hasMore()) { + //only restore file copies, do nothing if file has been completely deleted in CTA + cta::common::dataStructures::ArchiveFile archiveFile = itor.next(); + if (archiveFile.tapeFiles.find(fileRecycleLog.copyNb) != archiveFile.tapeFiles.end()) { + //copy with same copy_nb exists, cannot restore + UserSpecifiedExistingDeletedFileCopy ex; + ex.getMessage() << "Cannot restore file copy with archiveFileId " << std::to_string(fileRecycleLog.archiveFileId) + << " and copy_nb " << std::to_string(fileRecycleLog.copyNb) << " because a tapefile with same archiveFileId and copy_nb already exists"; + throw ex; + } + restoreFileCopyInRecycleLog(conn, fileRecycleLog, lc); + } + } + conn.commit(); + + log::ScopedParamContainer spc(lc); + tl.insertAndReset("commitTime",t); + tl.addToLog(spc); + lc.log(log::INFO,"In SqliteCatalogue::restoreFileCopiesInRecycleLog: all file copies successfully restored."); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + +//------------------------------------------------------------------------------ +// restoreFileCopyInRecycleLog +//------------------------------------------------------------------------------ +void SqliteCatalogue::restoreFileCopyInRecycleLog(rdbms::Conn &conn, const common::dataStructures::FileRecycleLog &fileRecycleLog, log::LogContext & lc) { + try { + utils::Timer t; + log::TimingList tl; + cta::common::dataStructures::TapeFile tapeFile; + tapeFile.vid = fileRecycleLog.vid; + tapeFile.fSeq = fileRecycleLog.fSeq; + tapeFile.copyNb = fileRecycleLog.copyNb; + tapeFile.blockId = fileRecycleLog.blockId; + tapeFile.fileSize = fileRecycleLog.sizeInBytes; + tapeFile.creationTime = fileRecycleLog.tapeFileCreationTime; + + insertTapeFile(conn, tapeFile, fileRecycleLog.archiveFileId); + tl.insertAndReset("insertTapeFileTime",t); + + deleteTapeFileCopyFromRecycleBin(conn, fileRecycleLog); + tl.insertAndReset("deleteTapeFileCopyFromRecycleBinTime",t); + + log::ScopedParamContainer spc(lc); + spc.add("vid", tapeFile.vid); + spc.add("archiveFileId", fileRecycleLog.archiveFileId); + spc.add("fSeq", tapeFile.fSeq); + spc.add("copyNb", tapeFile.copyNb); + spc.add("fileSize", tapeFile.fileSize); + tl.addToLog(spc); + lc.log(log::INFO,"In SqliteCatalogue::restoreFileCopyInRecycleLog: File restored from the recycle log."); + } catch(exception::UserError &) { + throw; + } catch(exception::Exception &ex) { + ex.getMessage().str(std::string(__FUNCTION__) + ": " + ex.getMessage().str()); + throw; + } +} + } // namespace catalogue } // namespace cta diff --git a/catalogue/SqliteCatalogue.hpp b/catalogue/SqliteCatalogue.hpp index 4102a8532ba2b638de1643b88859246f99aed3aa..70394195df73617de384388c2f98d67583983fb0 100644 --- a/catalogue/SqliteCatalogue.hpp +++ b/catalogue/SqliteCatalogue.hpp @@ -227,6 +227,24 @@ protected: void copyTapeFileToFileRecyleLogAndDelete(rdbms::Conn & conn, const cta::common::dataStructures::ArchiveFile &file, const std::string &reason, log::LogContext & lc) override; + /** + * Copy the files in fileRecycleLogItor to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entries + * @param conn the database connection + * @param fileRecycleLogItor the collection of fileRecycleLogs we want to restore + * @param lc the log context + */ + void restoreFileCopiesInRecycleLog(rdbms::Conn & conn, FileRecycleLogItor &fileRecycleLogItor, log::LogContext & lc) override; + + /** + * Copy the fileRecycleLog to the TAPE_FILE table and deletes the corresponding FILE_RECYCLE_LOG table entry + * @param conn the database connection + * @param fileRecycleLog the fileRecycleLog we want to restore + * @param lc the log context + */ + void restoreFileCopyInRecycleLog(rdbms::Conn & conn, const common::dataStructures::FileRecycleLog &fileRecycleLogItor, log::LogContext & lc); + + + private: /** diff --git a/catalogue/TapeFileSearchCriteria.hpp b/catalogue/TapeFileSearchCriteria.hpp index df604f20d1fff7f9f1c94e94da2ab5679cd3d339..efd52ab41e7d1f5ea195a7dffb2f79757d3d9d29 100644 --- a/catalogue/TapeFileSearchCriteria.hpp +++ b/catalogue/TapeFileSearchCriteria.hpp @@ -47,6 +47,11 @@ struct TapeFileSearchCriteria { */ optional<std::string> vid; + /** + * The fSeq of the file on tape. + */ + optional<uint64_t> fSeq; + /** * List of disk file IDs. * diff --git a/catalogue/common_catalogue_schema.sql b/catalogue/common_catalogue_schema.sql index b0fbdc2adf7871cafde16894227fea24d5ef5509..6443c3d985300e96108769cd732e416c9aa2b35c 100644 --- a/catalogue/common_catalogue_schema.sql +++ b/catalogue/common_catalogue_schema.sql @@ -39,6 +39,7 @@ CREATE TABLE VIRTUAL_ORGANIZATION( VIRTUAL_ORGANIZATION_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_VON_NN NOT NULL, READ_MAX_DRIVES UINT64TYPE CONSTRAINT VIRTUAL_ORGANIZATION_RMD_NN NOT NULL, WRITE_MAX_DRIVES UINT64TYPE CONSTRAINT VIRTUAL_ORGANIZATION_WMD_NN NOT NULL, + MAX_FILE_SIZE UINT64TYPE CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL, USER_COMMENT VARCHAR(1000) CONSTRAINT VIRTUAL_ORGANIZATION_UC_NN NOT NULL, CREATION_LOG_USER_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLUN_NN NOT NULL, CREATION_LOG_HOST_NAME VARCHAR(100) CONSTRAINT VIRTUAL_ORGANIZATION_CLHN_NN NOT NULL, diff --git a/catalogue/migrations/liquibase/oracle/4.1to4.2.sql b/catalogue/migrations/liquibase/oracle/4.1to4.2.sql new file mode 100644 index 0000000000000000000000000000000000000000..e76b7c4c018561a166f707884a2f5dd8d279d613 --- /dev/null +++ b/catalogue/migrations/liquibase/oracle/4.1to4.2.sql @@ -0,0 +1,33 @@ +--liquibase formatted sql + +--changeset mvelosob:1 failOnError:true dbms:oracle +--preconditions onFail:HALT onError:HALT +--precondition-sql-check expectedResult:"4.1" SELECT CONCAT(CONCAT(CAST(SCHEMA_VERSION_MAJOR as VARCHAR(10)),'.'), CAST(SCHEMA_VERSION_MINOR AS VARCHAR(10))) AS CATALOGUE_VERSION FROM CTA_CATALOGUE; +UPDATE CTA_CATALOGUE SET STATUS='UPGRADING'; +UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MAJOR=4; +UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MINOR=2; +--rollback UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MAJOR=NULL; +--rollback UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MINOR=NULL; +--rollback UPDATE CTA_CATALOGUE SET STATUS='PRODUCTION'; + +--changeset mvelosob:2 failOnError:true dbms:oracle +--preconditions onFail:HALT onError:HALT +--precondition-sql-check expectedResult:"4.1" SELECT CONCAT(CONCAT(CAST(SCHEMA_VERSION_MAJOR as VARCHAR(10)),'.'), CAST(SCHEMA_VERSION_MINOR AS VARCHAR(10))) AS CATALOGUE_VERSION FROM CTA_CATALOGUE; +ALTER TABLE VIRTUAL_ORGANIZATION ADD (MAX_FILE_SIZE NUMERIC(20, 0)); +UPDATE VIRTUAL_ORGANIZATION SET MAX_FILE_SIZE=128849018880; +ALTER TABLE VIRTUAL_ORGANIZATION MODIFY MAX_FILE_SIZE CONSTRAINT VIRTUAL_ORGANIZATION_MFS_NN NOT NULL; +--rollback ALTER TABLE VIRTUAL_ORGANIZATION DROP COLUMN MAX_FILE_SIZE + +--changeset mvelosob:3 failOnError:true dbms:oracle +--preconditions onFail:HALT onError:HALT +--precondition-sql-check expectedResult:"4.1" SELECT CONCAT(CONCAT(CAST(SCHEMA_VERSION_MAJOR as VARCHAR(10)),'.'), CAST(SCHEMA_VERSION_MINOR AS VARCHAR(10))) AS CATALOGUE_VERSION FROM CTA_CATALOGUE; +UPDATE CTA_CATALOGUE SET STATUS='PRODUCTION'; +UPDATE CTA_CATALOGUE SET SCHEMA_VERSION_MAJOR=4; +UPDATE CTA_CATALOGUE SET SCHEMA_VERSION_MINOR=2; +UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MAJOR=NULL; +UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MINOR=NULL; +--rollback UPDATE CTA_CATALOGUE SET STATUS='UPGRADING'; +--rollback UPDATE CTA_CATALOGUE SET SCHEMA_VERSION_MAJOR=4; +--rollback UPDATE CTA_CATALOGUE SET SCHEMA_VERSION_MINOR=1; +--rollback UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MAJOR=4; +--rollback UPDATE CTA_CATALOGUE SET NEXT_SCHEMA_VERSION_MINOR=2; diff --git a/cmake/CTAVersions.cmake b/cmake/CTAVersions.cmake index 13f75929eb1e51494859e76a085d3fa9c6563df4..6ee868bdcf94fff06002e94577549b6b0e632e31 100644 --- a/cmake/CTAVersions.cmake +++ b/cmake/CTAVersions.cmake @@ -19,7 +19,7 @@ set(XROOTD_SSI_PROTOBUF_INTERFACE_VERSION "v0.0") # Catalogue Schema Version set(CTA_CATALOGUE_SCHEMA_VERSION_MAJOR 4) -set(CTA_CATALOGUE_SCHEMA_VERSION_MINOR 1) +set(CTA_CATALOGUE_SCHEMA_VERSION_MINOR 2) # Shared object internal version (used in SONAME) set(CTA_SOVERSION 0) diff --git a/cmdline/CtaAdminCmd.cpp b/cmdline/CtaAdminCmd.cpp index 334e55dc4ddb09edd295d03c4ed47977f66d947e..eb600d7df98b7d5d967ea15a43f604d2f37e0d1b 100644 --- a/cmdline/CtaAdminCmd.cpp +++ b/cmdline/CtaAdminCmd.cpp @@ -34,6 +34,8 @@ std::atomic<bool> isHeaderSent(false); cta::admin::TextFormatter formattedText(1000); +std::string tp_config_file = "/etc/cta/TPCONFIG"; + namespace XrdSsiPb { /*! @@ -229,7 +231,7 @@ void CtaAdminCmd::send() const } catch(std::runtime_error &ex) { throwUsage(ex.what()); } - + // Set configuration options const std::string config_file = "/etc/cta/cta-cli.conf"; XrdSsiPb::Config config(config_file, "cta"); @@ -346,7 +348,36 @@ void CtaAdminCmd::parseOptions(int start, int argc, const char *const *const arg } } +std::string CtaAdminCmd::getDriveFromTpConfig() { + std::ifstream file(tp_config_file); + if (file.fail()) { + throw std::runtime_error("Unable to open file " + tp_config_file); + } + + std::string line; + while(std::getline(file, line)) { + // Strip out comments + auto pos = line.find('#'); + if(pos != std::string::npos) { + line.resize(pos); + } + + // Extract the list items + std::stringstream ss(line); + while(!ss.eof()) { + std::string item; + ss >> item; + // skip blank lines or lines consisting only of whitespace + if(item.empty()) continue; + + std::string drivename = item.substr(0, item.find(" ")); // first word of line + return drivename; + + } + } + throw std::runtime_error("File " + tp_config_file + " is empty"); +} void CtaAdminCmd::addOption(const Option &option, const std::string &value) { @@ -359,7 +390,11 @@ void CtaAdminCmd::addOption(const Option &option, const std::string &value) auto key = strOptions.at(option.get_key()); auto new_opt = admincmd_ptr->add_option_str(); new_opt->set_key(key); - new_opt->set_value(value); + if (option == opt_drivename_cmd && value == "first") { + new_opt->set_value(getDriveFromTpConfig()); + } else { + new_opt->set_value(value); + } break; } case Option::OPT_STR_LIST: { diff --git a/cmdline/CtaAdminCmd.hpp b/cmdline/CtaAdminCmd.hpp index fa5bfee36f7be15aa64a1c59f455859a93381966..3c53f016f0551d242c1314599780895fb4ce9fe5 100644 --- a/cmdline/CtaAdminCmd.hpp +++ b/cmdline/CtaAdminCmd.hpp @@ -49,6 +49,9 @@ private: //! Add a valid option to the protocol buffer void addOption(const Option &option, const std::string &value); + //! Parses the TPCONFIG file to obtain the first drive in the tapeserver + std::string getDriveFromTpConfig(); + //! Read a list of string options from a file void readListFromFile(cta::admin::OptionStrList &str_list, const std::string &filename); diff --git a/cmdline/CtaAdminCmdParse.hpp b/cmdline/CtaAdminCmdParse.hpp index 3d4d1a377989c2e06e943eb6e4330d4cf8517dcf..3fd5377c36a37627509c4185376ad58b6a7c4340 100644 --- a/cmdline/CtaAdminCmdParse.hpp +++ b/cmdline/CtaAdminCmdParse.hpp @@ -66,6 +66,13 @@ public: return option == m_short_opt || option == m_long_opt; } + /*! + * Check if the supplied option matches the option + */ + bool operator==(const Option &option) const { + return option == m_short_opt || option == m_long_opt; + } + /*! * Return the type of this option */ @@ -238,6 +245,7 @@ const subcmdLookup_t subcmdLookup = { { "rm", AdminCmd::SUBCMD_RM }, { "up", AdminCmd::SUBCMD_UP }, { "down", AdminCmd::SUBCMD_DOWN }, + { "restore", AdminCmd::SUBCMD_RESTORE } }; @@ -276,6 +284,7 @@ const std::map<std::string, OptionUInt64::Key> uint64Options = { { "--capacity", OptionUInt64::CAPACITY }, { "--copynb", OptionUInt64::COPY_NUMBER }, { "--id", OptionUInt64::ARCHIVE_FILE_ID }, + {"--maxfilesize", OptionUInt64::MAX_FILE_SIZE}, { "--maxlpos", OptionUInt64::MAX_LPOS }, { "--minarchiverequestage", OptionUInt64::MIN_ARCHIVE_REQUEST_AGE }, { "--minlpos", OptionUInt64::MIN_LPOS }, @@ -345,7 +354,9 @@ const std::map<AdminCmd::Cmd, CmdHelp> cmdHelp = { "\n This is a synchronous command that sets and reads back the state of one or\n" " more drives. The <drive_name> option accepts a regular expression. If the\n" " --force option is not set, the drives will complete any running mount and\n" - " drives must be in the down state before deleting.\n\n" + " drives must be in the down state before deleting. If the <drive_name> option\n" + " is set to first, the up, down, ls and ch commands will use the first drive\n" + " listed in TPCONFIG\n\n" }}, { AdminCmd::CMD_FAILEDREQUEST, { "failedrequest", "fr", { "ls", "rm" } }}, { AdminCmd::CMD_GROUPMOUNTRULE, { "groupmountrule", "gmr", { "add", "ch", "rm", "ls" } }}, @@ -404,14 +415,17 @@ const std::map<AdminCmd::Cmd, CmdHelp> cmdHelp = { " * Specify the name (--vo) of the virtual organization. It must be unique.\n" " * Specify the maximum number of drives the virtual organization is allowed to use for writing with the --writemaxdrives parameter\n" " * Specify the maximum number of drives the virtual organization is allowed to use for reading with the --readmaxdrives parameter\n" - " * Specify the comment (--comment) associated to the virtual organization" + " * Specify the comment (--comment) associated to the virtual organization\n" + " * Specify the maximum file size (--maxfilesize) associated to the virtual organization (optional, a value of 0 means no limit)" "\n\n" }}, { AdminCmd::CMD_VERSION, { "version", "v", { } }}, { AdminCmd::CMD_SCHEDULINGINFOS, { "schedulinginfo", "si", { "ls" } }}, - { AdminCmd::CMD_RECYCLETAPEFILE, { "recycletf", "rtf", { "ls" }, + { AdminCmd::CMD_RECYCLETAPEFILE, { "recycletf", "rtf", { "ls", "restore" }, + " This command allows to manage files in the recycle log.\n" " Tape files in the recycle log can be listed by VID, EOS disk file ID, EOS disk instance, ArchiveFileId or copy number.\n" - " Disk file IDs should be provided in hexadecimal (fxid).\n\n" }}, + " Disk file IDs should be provided in hexadecimal (fxid).\n" + " Deleted files can be restored with the restore command\n\n" }}, }; @@ -429,7 +443,6 @@ const Option opt_comment { Option::OPT_STR, "--comment", const Option opt_copynb { Option::OPT_UINT, "--copynb", "-c", " <copy_number>" }; const Option opt_copynb_alias { Option::OPT_UINT, "--numberofcopies", "-c", " <number_of_copies>", "--copynb" }; const Option opt_disabled { Option::OPT_BOOL, "--disabled", "-d", " <\"true\" or \"false\">" }; -const Option opt_drivename { Option::OPT_STR, "--drive", "-d", " <drive_name>" }; const Option opt_drivename_cmd { Option::OPT_CMD, "--drive", "", "<drive_name>" }; const Option opt_encrypted { Option::OPT_BOOL, "--encrypted", "-e", " <\"true\" or \"false\">" }; const Option opt_encryptionkeyname { Option::OPT_STR, "--encryptionkeyname", "-k", " <encryption_key_name>" }; @@ -448,6 +461,7 @@ const Option opt_log { Option::OPT_FLAG, "--log", const Option opt_logicallibrary { Option::OPT_STR, "--logicallibrary", "-l", " <logical_library_name>" }; const Option opt_logicallibrary_alias { Option::OPT_STR, "--name", "-n", " <logical_library_name>", "--logicallibrary" }; const Option opt_lookupns { Option::OPT_FLAG, "--lookupnamespace", "-l", "" }; +const Option opt_maxfilesize { Option::OPT_UINT, "--maxfilesize", "-mfs", " <maximum_file_size>" }; const Option opt_maxlpos { Option::OPT_UINT, "--maxlpos", "-maxl", " <maximum_longitudinal_position>" }; const Option opt_mediatype { Option::OPT_STR, "--mediatype", "--mt", " <media_type_name>" }; const Option opt_mediatype_alias { Option::OPT_STR, "--name", "-n", " <media_type_name>", "--mediatype" }; @@ -470,6 +484,7 @@ const Option opt_tapepool { Option::OPT_STR, "--tapepool", const Option opt_tapepool_alias { Option::OPT_STR, "--name", "-n", " <tapepool_name>", "--tapepool" }; const Option opt_username { Option::OPT_STR, "--username", "-u", " <user_name>" }; const Option opt_username_alias { Option::OPT_STR, "--name", "-n", " <user_name>", "--username" }; +const Option opt_groupname_alias { Option::OPT_STR, "--name", "-n", " <group_name>", "--username" }; const Option opt_vendor { Option::OPT_STR, "--vendor", "--ve", " <vendor>" }; const Option opt_vid { Option::OPT_STR, "--vid", "-v", " <vid>" }; const Option opt_vo { Option::OPT_STR, "--virtualorganisation", "--vo", " <virtual_organisation>" }; @@ -508,8 +523,8 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_UP }, { opt_drivename_cmd, opt_reason.optional() }}, {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_DOWN }, { opt_drivename_cmd, opt_reason, opt_force_flag.optional() }}, - {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_LS }, { opt_drivename.optional() }}, - {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_RM }, { opt_drivename_cmd, opt_force_flag.optional() }}, + {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_LS }, { opt_drivename_cmd.optional() }}, + {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_RM }, { opt_drivename_cmd, opt_force_flag.optional()}}, {{ AdminCmd::CMD_DRIVE, AdminCmd::SUBCMD_CH }, { opt_drivename_cmd, opt_comment }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_FAILEDREQUEST, AdminCmd::SUBCMD_LS }, @@ -518,10 +533,10 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_FAILEDREQUEST, AdminCmd::SUBCMD_RM }, { opt_object_id }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_ADD }, - { opt_instance, opt_username_alias, opt_mountpolicy, opt_comment }}, + { opt_instance, opt_groupname_alias, opt_mountpolicy, opt_comment }}, {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_CH }, - { opt_instance, opt_username_alias, opt_mountpolicy.optional(), opt_comment.optional() }}, - {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_RM }, { opt_instance, opt_username_alias }}, + { opt_instance, opt_groupname_alias, opt_mountpolicy.optional(), opt_comment.optional() }}, + {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_RM }, { opt_instance, opt_groupname_alias }}, {{ AdminCmd::CMD_GROUPMOUNTRULE, AdminCmd::SUBCMD_LS }, { }}, /*----------------------------------------------------------------------------------------------------*/ {{ AdminCmd::CMD_LOGICALLIBRARY, AdminCmd::SUBCMD_ADD }, @@ -609,9 +624,9 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_DISKSYSTEM, AdminCmd::SUBCMD_RM }, { opt_disksystem }}, {{ AdminCmd::CMD_DISKSYSTEM, AdminCmd::SUBCMD_LS }, { }}, {{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_ADD }, - { opt_vo, opt_read_max_drives, opt_write_max_drives, opt_comment }}, + { opt_vo, opt_read_max_drives, opt_write_max_drives, opt_comment, opt_maxfilesize.optional() }}, {{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_CH }, - { opt_vo, opt_comment.optional(), opt_read_max_drives.optional(), opt_write_max_drives.optional() }}, + { opt_vo, opt_comment.optional(), opt_read_max_drives.optional(), opt_write_max_drives.optional(), opt_maxfilesize.optional() }}, {{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_RM }, { opt_vo }}, {{ AdminCmd::CMD_VIRTUALORGANIZATION, AdminCmd::SUBCMD_LS }, @@ -620,6 +635,8 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { {{ AdminCmd::CMD_SCHEDULINGINFOS, AdminCmd::SUBCMD_LS }, { }}, {{ AdminCmd::CMD_RECYCLETAPEFILE, AdminCmd::SUBCMD_LS }, { opt_vid.optional(), opt_fid.optional(), opt_fidfile.optional(), opt_copynb.optional(), opt_archivefileid.optional(), opt_instance.optional() }}, + {{ AdminCmd::CMD_RECYCLETAPEFILE, AdminCmd::SUBCMD_RESTORE }, + { opt_vid.optional(), opt_fid.optional(), opt_fidfile.optional(), opt_copynb.optional(), opt_archivefileid.optional(), opt_instance.optional() }}, }; @@ -630,5 +647,4 @@ const std::map<cmd_key_t, cmd_val_t> cmdOptions = { * Throws a std::runtime_error if the command is invalid */ void validateCmd(const cta::admin::AdminCmd &admincmd); - }} // namespace cta::admin diff --git a/cmdline/CtaAdminTextFormatter.cpp b/cmdline/CtaAdminTextFormatter.cpp index 80ca2425d7e6f369ac37f8f17944229b8a7c1124..986fac9961d1a766f56ad0700c2260ed03091f85 100644 --- a/cmdline/CtaAdminTextFormatter.cpp +++ b/cmdline/CtaAdminTextFormatter.cpp @@ -994,6 +994,7 @@ void TextFormatter::printVirtualOrganizationLsHeader(){ "name", "read max drives", "write max drives", + "max file size", "c.user", "c.host", "c.time", @@ -1009,6 +1010,7 @@ void TextFormatter::print(const VirtualOrganizationLsItem& vols_item){ vols_item.name(), vols_item.read_max_drives(), vols_item.write_max_drives(), + dataSizeToStr(vols_item.max_file_size()), vols_item.creation_log().username(), vols_item.creation_log().host(), timeToStr(vols_item.creation_log().time()), diff --git a/common/dataStructures/VirtualOrganization.hpp b/common/dataStructures/VirtualOrganization.hpp index df28140a35e7e4804d287a398351046e4576214d..a8d31b04426111b83104b64327fc2311f6b7c4cd 100644 --- a/common/dataStructures/VirtualOrganization.hpp +++ b/common/dataStructures/VirtualOrganization.hpp @@ -41,6 +41,12 @@ struct VirtualOrganization { * Max number of drives allocated for writing per VO */ uint64_t writeMaxDrives; + + /** + * Max size of files belonging to VO + */ + uint64_t maxFileSize; + /** * The creation log. */ @@ -52,7 +58,8 @@ struct VirtualOrganization { EntryLog lastModificationLog; bool operator==(const VirtualOrganization & other) const{ - return (name == other.name && comment == other.comment && readMaxDrives == other.readMaxDrives && writeMaxDrives == other.writeMaxDrives); + return (name == other.name && comment == other.comment && readMaxDrives == other.readMaxDrives && + writeMaxDrives == other.writeMaxDrives && maxFileSize == other.maxFileSize); } }; diff --git a/continuousintegration/buildtree_runner/vmBootstrap/bootstrapCTA.sh b/continuousintegration/buildtree_runner/vmBootstrap/bootstrapCTA.sh index ee35b5f822f09a203375d634279c6bd5dc9ec106..2168fd66a709c759fe7f4e5647a3e30ce59c71dd 100755 --- a/continuousintegration/buildtree_runner/vmBootstrap/bootstrapCTA.sh +++ b/continuousintegration/buildtree_runner/vmBootstrap/bootstrapCTA.sh @@ -63,6 +63,7 @@ echo Installing build dependencies sudo yum-builddep -y ~/CTA-build-srpm/RPM/SRPMS/cta-0-1.src.rpm echo Building CTA +rm -rf ~/CTA-build mkdir -p ~/CTA-build (cd ~/CTA-build && cmake ../CTA; make -j 4) diff --git a/cta.spec.in b/cta.spec.in index fd91fa999a9155e78d4e9b9b056037780a2dfd4b..fa403efb3cab4ee499ab5b74399b8eea4e526cb7 100644 --- a/cta.spec.in +++ b/cta.spec.in @@ -441,6 +441,22 @@ The command-line tool for pre-labelling a CTA tape. %post -n cta-tape-label /usr/sbin/setcap cap_sys_rawio+ep %{_bindir}/cta-tape-label +%package -n cta-readtp +Summary: The command-line tool for reading files from a CTA tape. +Group: Application/CTA +Requires: cta-lib = %{version}-%{release} +Requires: xrootd-client-libs >= %{xrootdVersion} +Requires(post): /usr/sbin/setcap +%description -n cta-readtp +CERN Tape Archive: +The command-line tool for reading files from a CTA tape. +%files -n cta-readtp +%defattr(-,root,root) +%attr(0750,cta,tape) %{_bindir}/cta-readtp +%attr(0644,root,root) %doc /usr/share/man/man1/cta-readtp.1cta.gz +%post -n cta-readtp +/usr/sbin/setcap cap_sys_rawio+ep %{_bindir}/cta-readtp + %package -n cta-common Summary: CERN Tape Archive common items Group: Application/CTA @@ -513,6 +529,12 @@ Remember to add its content to "%{_sysconfdir}/yum/pluginconf.d/versionlock.list EOF %changelog +* Wed Aug 18 2021 volodymyr.yurchenko (at) cern.ch - 4.1-1 +- cta/CTA#1016 New options for filtering deleted files using `cta-admin rtf ls` command. +- cta/CTA#983 Add cta-release package for public binary rpm distribution. +- cta/CTA#980 Add external encryption script option +- [frontend] New command "tapefile rm" allows deleting a copy of a file from tape +- cta/CTA#1014 Fix last column alignment when more than 1000 items are listed. * Tue Jul 27 2021 julien.leduc (at) cern.ch - 4.0-5 - [frontend] Add options to "tapepool ls" to filter tapepools on their name, vo and encryption - cta/CTA#898 cta-send-event now gets the requester id and eos instance as command line arguments diff --git a/scheduler/SchedulerTest.cpp b/scheduler/SchedulerTest.cpp index 6b91d36bfb09085e048b31cd085c98ac6d42ac95..cb3f1d6e7324b2e2432c17b2c7a09f8f55eb37b9 100644 --- a/scheduler/SchedulerTest.cpp +++ b/scheduler/SchedulerTest.cpp @@ -212,6 +212,7 @@ public: vo.comment = "comment"; vo.writeMaxDrives = 1; vo.readMaxDrives = 1; + vo.maxFileSize = 0; m_catalogue->createVirtualOrganization(s_adminOnAdminHost,vo); common::dataStructures::StorageClass storageClass; @@ -706,6 +707,7 @@ TEST_P(SchedulerTest, archive_report_and_retrieve_new_dual_copy_file) { vo.comment = "comment"; vo.writeMaxDrives = 1; vo.readMaxDrives = 1; + vo.maxFileSize = 0; catalogue.createVirtualOrganization(s_adminOnAdminHost,vo); common::dataStructures::StorageClass storageClass; diff --git a/tapeserver/CMakeLists.txt b/tapeserver/CMakeLists.txt index 8e94972cb38ccfde9feec7e0c0775006bba6664d..6f492b91cb296421ecb32cf20bbe48f8c123b8bf 100644 --- a/tapeserver/CMakeLists.txt +++ b/tapeserver/CMakeLists.txt @@ -23,6 +23,7 @@ add_subdirectory (session) # The tape session's threads are in a separate directory (session, but compiled # from the previous one to create a single library). add_subdirectory (tapelabel) +add_subdirectory (readtp) include_directories (${PROTOBUF3_INCLUDE_DIRS}) add_executable (cta-taped cta-taped.cpp) diff --git a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp index eb0f2b1ed606d9db864dd02b6a8728222d3f09ce..fd04f5e65483abe0327d67c38faf9cbb05471d2f 100644 --- a/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp +++ b/tapeserver/castor/tape/tapeserver/daemon/DataTransferSessionTest.cpp @@ -279,6 +279,7 @@ public: vo.name = "vo"; vo.readMaxDrives = 1; vo.writeMaxDrives = 1; + vo.maxFileSize = 0; vo.comment = "comment"; return vo; } @@ -2322,21 +2323,24 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullMigration) { std::string temp = logger.getLog(); temp += ""; ASSERT_EQ(s_vid, sess.getVid()); - auto afiiter = archiveFileIds.begin(); - size_t archiveFileCount = 0; - for(auto & sf: sourceFiles) { - auto afi = *(afiiter++); - archiveFileCount++; + cta::catalogue::TapeFileSearchCriteria criteria; + auto afsItor = catalogue.getArchiveFilesItor(criteria); + for (size_t i = 1; i <= sourceFiles.size(); ++i) { // Only the first files made it through. - if (archiveFileCount <= 3) { - auto afs = catalogue.getArchiveFileById(afi); + if (i <= 3) { + ASSERT_TRUE(afsItor.hasMore()); + auto afs = afsItor.next(); ASSERT_EQ(1, afs.tapeFiles.size()); cta::checksum::ChecksumBlob checksumBlob; - checksumBlob.insert(cta::checksum::ADLER32, sf->adler32()); + // Get the element of the list sourceFiles correspondent with afs.archiveFileID (https://stackoverflow.com/a/16747600) + // archiveFileID starts on "1" that's why it removes one position in the list + auto sourceFiles_front = sourceFiles.begin(); + std::advance(sourceFiles_front, afs.archiveFileID - 1); + checksumBlob.insert(cta::checksum::ADLER32, (*sourceFiles_front)->adler32()); ASSERT_EQ(afs.checksumBlob, checksumBlob); ASSERT_EQ(1000, afs.fileSize); } else { - ASSERT_THROW(catalogue.getArchiveFileById(afi), cta::exception::Exception); + ASSERT_FALSE(afsItor.hasMore()); } // The tape should now be marked as full cta::catalogue::TapeSearchCriteria crit; @@ -2485,21 +2489,24 @@ TEST_P(DataTransferSessionTest, DataTransferSessionTapeFullOnFlushMigration) { std::string temp = logger.getLog(); temp += ""; ASSERT_EQ(s_vid, sess.getVid()); - auto afiiter = archiveFileIds.begin(); - size_t archiveFileCount = 0; - for(auto & sf: sourceFiles) { - auto afi = *(afiiter++); - archiveFileCount++; + cta::catalogue::TapeFileSearchCriteria criteria; + auto afsItor = catalogue.getArchiveFilesItor(criteria); + for (size_t i = 1; i <= sourceFiles.size(); ++i) { // Only the first files made it through. - if (archiveFileCount <= 3) { - auto afs = catalogue.getArchiveFileById(afi); + if (i <= 3) { + ASSERT_TRUE(afsItor.hasMore()); + auto afs = afsItor.next(); ASSERT_EQ(1, afs.tapeFiles.size()); cta::checksum::ChecksumBlob checksumBlob; - checksumBlob.insert(cta::checksum::ADLER32, sf->adler32()); + // Get the element of the list sourceFiles correspondent with afs.archiveFileID (https://stackoverflow.com/a/16747600) + // archiveFileID starts on "1" that's why it removes one position in the list + auto sourceFiles_front = sourceFiles.begin(); + std::advance(sourceFiles_front, afs.archiveFileID - 1); + checksumBlob.insert(cta::checksum::ADLER32, (*sourceFiles_front)->adler32()); ASSERT_EQ(afs.checksumBlob, checksumBlob); ASSERT_EQ(1000, afs.fileSize); } else { - ASSERT_THROW(catalogue.getArchiveFileById(afi), cta::exception::Exception); + ASSERT_FALSE(afsItor.hasMore()); } // The tape should now be marked as full cta::catalogue::TapeSearchCriteria crit; diff --git a/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp b/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp index df3e47b3d6a939d6ec1b512843d33740941296e7..99829be23eb68090c12a7c2a214d7272855b558e 100644 --- a/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp +++ b/tapeserver/castor/tape/tapeserver/daemon/MigrationReportPackerTest.cpp @@ -70,6 +70,7 @@ const uint32_t TEST_GROUP_2 = 9754; vo.name = "vo"; vo.readMaxDrives = 1; vo.writeMaxDrives = 1; + vo.maxFileSize = 0; vo.comment = "comment"; return vo; } diff --git a/tapeserver/castor/tape/tapeserver/daemon/TapeReadSingleThread.cpp b/tapeserver/castor/tape/tapeserver/daemon/TapeReadSingleThread.cpp index a0b122c996e99804ac2642f14dad558ddafa1b83..675a8e22cc4d02b5701bcb5781b557148e487ef5 100644 --- a/tapeserver/castor/tape/tapeserver/daemon/TapeReadSingleThread.cpp +++ b/tapeserver/castor/tape/tapeserver/daemon/TapeReadSingleThread.cpp @@ -376,7 +376,7 @@ void castor::tape::tapeserver::daemon::TapeReadSingleThread::run() { // This can happen late in the session, so we can still print the stats. cta::log::ScopedParamContainer params(m_logContext); params.add("status", "error") - .add("ErrorMesage", e.getMessageValue()); + .add("ErrorMessage", e.getMessageValue()); m_stats.totalTime = totalTimer.secs(); logWithStat(cta::log::INFO, "Tape thread complete", params); diff --git a/tapeserver/castor/tape/tapeserver/daemon/TapeWriteSingleThread.cpp b/tapeserver/castor/tape/tapeserver/daemon/TapeWriteSingleThread.cpp index c3e8cd5c9489dfae699a04bcd7f16d783eceb2bc..b4ee79fe3e6ee050f05c56061aa58a4e72a724ea 100644 --- a/tapeserver/castor/tape/tapeserver/daemon/TapeWriteSingleThread.cpp +++ b/tapeserver/castor/tape/tapeserver/daemon/TapeWriteSingleThread.cpp @@ -515,7 +515,7 @@ void castor::tape::tapeserver::daemon::TapeWriteSingleThread::run() { // then log the end of write thread cta::log::ScopedParamContainer params(m_logContext); params.add("status", "error") - .add("ErrorMesage", errorMessage); + .add("ErrorMessage", errorMessage); m_stats.totalTime = totalTimer.secs(); logWithStats(cta::log::INFO, "Tape thread complete", params); diff --git a/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp b/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp index 73a8b3c543c11fd8531c346cfb287ddd93f72bcd..b48328311d8f09424820d52e584fc7b0ad80bd05 100644 --- a/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp +++ b/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.cpp @@ -753,11 +753,43 @@ bool drive::DriveIBM3592::isEncryptionCapEnabled() { cta::exception::Errnum::throwOnMinusOne( m_sysWrapper.ioctl(this->m_tapeFD, SG_IO, &sgh), "Failed SG_IO ioctl in DriveIBM3592::isEncryptionCapEnabled"); - SCSI::ExceptionLauncher(sgh, "SCSI error in DriveIBM3592::clearEncryptionKey"); + SCSI::ExceptionLauncher(sgh, "SCSI error in DriveIBM3592::isEncryptionCapEnabled"); return SCSI::Structures::toU16(pl.supportedProtocolListLength) > 1; } +bool drive::DriveLTO::isEncryptionCapEnabled() { + /* + * Encryption enable support. Initially copied from IBM enterprise implementation. + */ + /* + * We are acquiring the encryption capability from the length of the SPIN index page. + * If it has one page (only 0x00), then encryption is disabled from the libary. + * If it has more pages, the encryption(0x00, 0x20 at the moment of writing), then it is enabled. + */ + SCSI::Structures::LinuxSGIO_t sgh; + SCSI::Structures::encryption::spinCDB_t cdb; + SCSI::Structures::senseData_t<255> senseBuff; + SCSI::Structures::encryption::spinPageList_t<20> pl; + + cdb.securityProtocol = SCSI::encryption::spinSecurityProtocolPages::securityProtocolInformation; + SCSI::Structures::setU16(cdb.securityProtocolSpecific, 0x0000); + SCSI::Structures::setU32(cdb.allocationLength, sizeof(pl)); + + sgh.setCDB(&cdb); + sgh.setDataBuffer(&pl); + sgh.setSenseBuffer(&senseBuff); + sgh.dxfer_direction = SG_DXFER_FROM_DEV; + + cta::exception::Errnum::throwOnMinusOne( + m_sysWrapper.ioctl(this->m_tapeFD, SG_IO, &sgh), + "Failed SG_IO ioctl in DriveLTO::isEncryptionCapEnabled"); + SCSI::ExceptionLauncher(sgh, "SCSI error in DriveLTO::isEncryptionCapEnabled"); + + return SCSI::Structures::toU16(pl.supportedProtocolListLength) > 1; +} + + bool drive::DriveT10000::isEncryptionCapEnabled() { /* * We are acquiring the encryption capability from the inquiry page on Oracle T10k drives diff --git a/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp b/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp index 575ea21c3b9edbd91de9490cd5313929f302243f..d22d1f8b15a0733db50f95bee948ee6cf23002f0 100644 --- a/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp +++ b/tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp @@ -589,6 +589,7 @@ namespace drive { virtual compressionStats getCompression(); virtual void clearCompressionStats(); virtual std::vector<castor::tape::tapeserver::drive::endOfWrapPosition> getEndOfWrapPositions(); + virtual bool isEncryptionCapEnabled(); }; class DriveIBM3592 : public DriveGeneric { diff --git a/tapeserver/cta-taped.1cta b/tapeserver/cta-taped.1cta index c755ed3817d5374d2d2912347f8cce5d23549a8d..6fc04eb924e4f53147c57e6a47811aa6f88faef4 100644 --- a/tapeserver/cta-taped.1cta +++ b/tapeserver/cta-taped.1cta @@ -141,6 +141,10 @@ The number of disk I/O threads. The protocol to be used when transferring files to and from disk servers. Possible values are RFIO or XROOT. The value is not case sensitive. +.TP +\fBtaped externalEncryptionKeyScript +The Python script to interface with the encryption data store. + .TP \fBXROOT PrivateKey The file hosting the Xroot private key, needed to sign Xroot URLs. diff --git a/tapeserver/daemon/DriveHandler.cpp b/tapeserver/daemon/DriveHandler.cpp index 856a38b17112a86c4fb98822ad1a70c709e5cc8d..f179ceabc12700efb4b63c82b97db4867559af9b 100644 --- a/tapeserver/daemon/DriveHandler.cpp +++ b/tapeserver/daemon/DriveHandler.cpp @@ -1069,6 +1069,7 @@ int DriveHandler::runChild() { dataTransferConfig.fetchEosFreeSpaceScript = m_tapedConfig.fetchEosFreeSpaceScript.value(); dataTransferConfig.tapeLoadTimeout = m_tapedConfig.tapeLoadTimeout.value(); dataTransferConfig.xrootPrivateKey = ""; + dataTransferConfig.externalEncryptionKeyScript = m_tapedConfig.externalEncryptionKeyScript.value(); // Before launching, and if this is the first session since daemon start, we will // put the drive down. diff --git a/tapeserver/daemon/MaintenanceHandler.cpp b/tapeserver/daemon/MaintenanceHandler.cpp index 9476a755d6d4ccbb9d3303390a19d73bbc03b8fc..3fda54d22346ccab1c3f25374ed01f8944bbf1d3 100644 --- a/tapeserver/daemon/MaintenanceHandler.cpp +++ b/tapeserver/daemon/MaintenanceHandler.cpp @@ -42,7 +42,7 @@ SubprocessHandler("maintenanceHandler"), m_processManager(pm), m_tapedConfig(tap } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::getInitialStatus +// MaintenanceHandler::getInitialStatus //------------------------------------------------------------------------------ SubprocessHandler::ProcessingStatus MaintenanceHandler::getInitialStatus() { m_processingStatus.forkRequested=true; @@ -50,7 +50,7 @@ SubprocessHandler::ProcessingStatus MaintenanceHandler::getInitialStatus() { } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::getInitialStatus +// MaintenanceHandler::getInitialStatus //------------------------------------------------------------------------------ void MaintenanceHandler::postForkCleanup() { // We are in the child process of another handler. We can close our socket pair @@ -62,7 +62,7 @@ void MaintenanceHandler::postForkCleanup() { //------------------------------------------------------------------------------ -// GarbageCollectorHandler::fork +// MaintenanceHandler::fork //------------------------------------------------------------------------------ SubprocessHandler::ProcessingStatus MaintenanceHandler::fork() { // If anything fails while attempting to fork, we will have to declare ourselves @@ -103,7 +103,7 @@ SubprocessHandler::ProcessingStatus MaintenanceHandler::fork() { } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::kill +// MaintenanceHandler::kill //------------------------------------------------------------------------------ void MaintenanceHandler::kill() { // If we have a subprocess, kill it and wait for completion (if needed). We do not need to keep @@ -136,7 +136,7 @@ void MaintenanceHandler::kill() { } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::processEvent +// MaintenanceHandler::processEvent //------------------------------------------------------------------------------ SubprocessHandler::ProcessingStatus MaintenanceHandler::processEvent() { // We do not expect any feedback for the child process... @@ -145,7 +145,7 @@ SubprocessHandler::ProcessingStatus MaintenanceHandler::processEvent() { } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::processSigChild +// MaintenanceHandler::processSigChild //------------------------------------------------------------------------------ SubprocessHandler::ProcessingStatus MaintenanceHandler::processSigChild() { // Check out child process's status. If the child process is still around, @@ -212,7 +212,7 @@ SubprocessHandler::ProcessingStatus MaintenanceHandler::processSigChild() { } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::processTimeout +// MaintenanceHandler::processTimeout //------------------------------------------------------------------------------ SubprocessHandler::ProcessingStatus MaintenanceHandler::processTimeout() { // The only time we expect a timeout is when shutting down @@ -236,7 +236,7 @@ SubprocessHandler::ProcessingStatus MaintenanceHandler::processTimeout() { } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::runChild +// MaintenanceHandler::runChild //------------------------------------------------------------------------------ int MaintenanceHandler::runChild() { try{ @@ -350,7 +350,7 @@ void MaintenanceHandler::exceptionThrowingRunChild(){ } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::shutdown +// MaintenanceHandler::shutdown //------------------------------------------------------------------------------ SubprocessHandler::ProcessingStatus MaintenanceHandler::shutdown() { // We will signal the shutdown to the child process by sending a byte over the @@ -366,7 +366,7 @@ SubprocessHandler::ProcessingStatus MaintenanceHandler::shutdown() { } //------------------------------------------------------------------------------ -// GarbageCollectorHandler::~GarbageCollectorHandler +// MaintenanceHandler::~MaintenanceHandler //------------------------------------------------------------------------------ MaintenanceHandler::~MaintenanceHandler() { // If we still have a child process (should not), just stop it the hard way. diff --git a/tapeserver/daemon/SubprocessHandler.hpp b/tapeserver/daemon/SubprocessHandler.hpp index c03fdd358f8701381ed564327730801efb702e3f..b8ad22d60fffe9284f36ad367036c904c25a3ffc 100644 --- a/tapeserver/daemon/SubprocessHandler.hpp +++ b/tapeserver/daemon/SubprocessHandler.hpp @@ -27,8 +27,8 @@ namespace daemon { /** * The interface to classes managing subprocesses. It allows an external loop * to handle global polling and timeouts for a set of them. Several children - * classes are expected to be developed: a DriveHandler, a GarbageCollector - * handler and a SignalHandler (using signalfd()). + * classes are expected to be developed: a DriveHandler, a MaintenanceHandler + * and a SignalHandler (using signalfd()). * The main loop will typically be: * statuses[] = [all]->getInitialStatus(); // This implicitly registers the right fds in epoll (if needed) * loop forever @@ -99,4 +99,4 @@ public: virtual int runChild() = 0; }; -}}} // namespace cta::tape::daemon \ No newline at end of file +}}} // namespace cta::tape::daemon diff --git a/tapeserver/daemon/TapedConfiguration.cpp b/tapeserver/daemon/TapedConfiguration.cpp index 530f63b4da07e46651700dba228cbfd33789e1d1..83b41062a478df4fa85833b35897ed9574193d8d 100644 --- a/tapeserver/daemon/TapedConfiguration.cpp +++ b/tapeserver/daemon/TapedConfiguration.cpp @@ -95,6 +95,7 @@ TapedConfiguration TapedConfiguration::createFromCtaConf( ret.daemonGroupName.setFromConfigurationFile(cf, generalConfigPath); ret.logMask.setFromConfigurationFile(cf, generalConfigPath); ret.tpConfigPath.setFromConfigurationFile(cf, generalConfigPath); + ret.externalEncryptionKeyScript.setFromConfigurationFile(cf, generalConfigPath); // Memory management ret.bufferSizeBytes.setFromConfigurationFile(cf, generalConfigPath); ret.bufferCount.setFromConfigurationFile(cf, generalConfigPath); @@ -137,6 +138,7 @@ TapedConfiguration TapedConfiguration::createFromCtaConf( ret.daemonGroupName.log(log); ret.logMask.log(log); ret.tpConfigPath.log(log); + ret.externalEncryptionKeyScript.log(log); ret.bufferSizeBytes.log(log); ret.bufferCount.log(log); @@ -149,7 +151,7 @@ TapedConfiguration TapedConfiguration::createFromCtaConf( ret.nbDiskThreads.log(log); ret.useRAO.log(log); - + ret.wdIdleSessionTimer.log(log); ret.wdMountMaxSecs.log(log); ret.wdNoBlockMoveMaxSecs.log(log); diff --git a/tapeserver/daemon/TapedConfiguration.hpp b/tapeserver/daemon/TapedConfiguration.hpp index d975ce72c1fb702c9a0debde3af8038965a86e1c..3c95ba98af3f5a6c3e9c39514c37e54fe17566ca 100644 --- a/tapeserver/daemon/TapedConfiguration.hpp +++ b/tapeserver/daemon/TapedConfiguration.hpp @@ -161,6 +161,13 @@ struct TapedConfiguration { cta::SourcedParameter<uint32_t> tapeLoadTimeout { "taped", "TapeLoadTimeout",60,"Compile time default" }; + + //---------------------------------------------------------------------------- + // Tape encryption script + //---------------------------------------------------------------------------- + cta::SourcedParameter<std::string> externalEncryptionKeyScript { + "taped", "externalEncryptionKeyScript","","Compile time default" + }; private: /** A private dummy logger which will simplify the implementation of the diff --git a/tapeserver/readtp/CMakeLists.txt b/tapeserver/readtp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..6607d13cd832fd4f0c136ae5d0ed84bbddae74d4 --- /dev/null +++ b/tapeserver/readtp/CMakeLists.txt @@ -0,0 +1,48 @@ +# @project The CERN Tape Archive (CTA) +# @copyright Copyright(C) 2015-2021 CERN +# @license This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +cmake_minimum_required (VERSION 2.6) + +include_directories(${CMAKE_SOURCE_DIR}/tapeserver) + +find_package( ZLIB REQUIRED ) + + +add_executable(cta-readtp + ReadtpCmd.cpp + ReadtpCmdMain.cpp + ReadtpCmdLineArgs.cpp + CmdLineTool.cpp + TapeFseqRange.cpp + TapeFseqRangeSequence.cpp + TapeFseqRangeListSequence.cpp + TapeFseqSequenceParser.cpp) + +target_link_libraries (cta-readtp + ctacommon + TapeDrive + ctamediachanger + ctacatalogue + SCSI +) + +# need to be removed when drop dependencies to taped +find_package(Protobuf3 REQUIRED) +set_property (TARGET cta-readtp APPEND PROPERTY INSTALL_RPATH ${PROTOBUF3_RPATH}) +if (OCCI_SUPPORT) + set_property (TARGET cta-readtp APPEND PROPERTY INSTALL_RPATH ${ORACLE-INSTANTCLIENT_RPATH}) +endif (OCCI_SUPPORT) + +install (TARGETS cta-readtp DESTINATION /usr/bin) +install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-readtp.1cta DESTINATION /usr/share/man/man1) \ No newline at end of file diff --git a/tapeserver/readtp/CmdLineTool.cpp b/tapeserver/readtp/CmdLineTool.cpp new file mode 100644 index 0000000000000000000000000000000000000000..bc1e38b077583de83c5c17b18f3f7b2c658e77a9 --- /dev/null +++ b/tapeserver/readtp/CmdLineTool.cpp @@ -0,0 +1,105 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "tapeserver/readtp/CmdLineTool.hpp" +#include "common/exception/CommandLineNotParsed.hpp" + +#include <unistd.h> + +namespace cta { +namespace tapeserver { +namespace readtp { + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +CmdLineTool::CmdLineTool( + std::istream &inStream, + std::ostream &outStream, + std::ostream &errStream) noexcept: + m_in(inStream), + m_out(outStream), + m_err(errStream) { +} + +//------------------------------------------------------------------------------ +// destructor +//------------------------------------------------------------------------------ +CmdLineTool::~CmdLineTool() noexcept { +} + +//------------------------------------------------------------------------------ +// getUsername +//------------------------------------------------------------------------------ +std::string CmdLineTool::getUsername() { + char buf[256]; + + if(getlogin_r(buf, sizeof(buf))) { + return "UNKNOWN"; + } else { + return buf; + } +} + +//------------------------------------------------------------------------------ +// getHostname +//------------------------------------------------------------------------------ +std::string CmdLineTool::getHostname() { + char buf[256]; + + if(gethostname(buf, sizeof(buf))) { + return "UNKNOWN"; + } else { + buf[sizeof(buf) - 1] = '\0'; + return buf; + } +} + +//------------------------------------------------------------------------------ +// main +//------------------------------------------------------------------------------ +int CmdLineTool::main(const int argc, char *const *const argv) { + bool cmdLineNotParsed = false; + std::string errorMessage; + + try { + return exceptionThrowingMain(argc, argv); + } catch(exception::CommandLineNotParsed &ue) { + errorMessage = ue.getMessage().str(); + cmdLineNotParsed = true; + } catch(exception::Exception &ex) { + errorMessage = ex.getMessage().str(); + } catch(std::exception &se) { + errorMessage = se.what(); + } catch(...) { + errorMessage = "An unknown exception was thrown"; + } + + // Reaching this point means the command has failed, an exception was throw + // and errorMessage has been set accordingly + + m_err << "Aborting: " << errorMessage << std::endl; + if(cmdLineNotParsed) { + m_err << std::endl; + printUsage(m_err); + } + return 1; +} + +} // namespace readtp +} // namespace tapeserver +} // namespace cta diff --git a/tapeserver/readtp/CmdLineTool.hpp b/tapeserver/readtp/CmdLineTool.hpp new file mode 100644 index 0000000000000000000000000000000000000000..90a236af75bbd7bd6c22a0b785cfea95ae307eb2 --- /dev/null +++ b/tapeserver/readtp/CmdLineTool.hpp @@ -0,0 +1,108 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <istream> +#include <ostream> + +namespace cta { +namespace tapeserver { +namespace readtp { + +/** + * Abstract class implementing common code and data structures for a + * command-line tool. + */ +class CmdLineTool { +public: + /** + * Constructor. + * + * @param inStream Standard input stream. + * @param outStream Standard output stream. + * @param errStream Standard error stream. + */ + CmdLineTool(std::istream &inStream, std::ostream &outStream, std::ostream &errStream) noexcept; + + /** + * Pure-virtual destructor to guarantee this class is abstract. + */ + virtual ~CmdLineTool() noexcept = 0; + + /** + * The object's implementation of main() that should be called from the main() + * of the program. + * + * @param argc The number of command-line arguments including the program name. + * @param argv The command-line arguments. + * @return The exit value of the program. + */ + int main(const int argc, char *const *const argv); + +protected: + + /** + * An exception throwing version of main(). + * + * @param argc The number of command-line arguments including the program name. + * @param argv The command-line arguments. + * @return The exit value of the program. + */ + virtual int exceptionThrowingMain(const int argc, char *const *const argv) = 0; + + /** + * Prints the usage message of the command-line tool. + * + * @param os The output stream to which the usage message is to be printed. + */ + virtual void printUsage(std::ostream &os) = 0; + + /** + * Standard input stream. + */ + std::istream &m_in; + + /** + * Standard output stream. + */ + std::ostream &m_out; + + /** + * Standard error stream. + */ + std::ostream &m_err; + + /** + * Returns the name of the user running the command-line tool. + * + * @return The name of the user running the command-line tool. + */ + static std::string getUsername(); + + /** + * Returns the name of the host on which the command-line tool is running. + * + * @return The name of the host on which the command-line tool is running. + */ + static std::string getHostname(); + +}; // class CmdLineTool + +} // namespace readtp +} // namespace tapeserver +} // namespace cta diff --git a/tapeserver/readtp/ReadtpCmd.cpp b/tapeserver/readtp/ReadtpCmd.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2419d83949c522701fb7ad8b1fe021a474fc7726 --- /dev/null +++ b/tapeserver/readtp/ReadtpCmd.cpp @@ -0,0 +1,588 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "common/Constants.hpp" +#include "common/log/DummyLogger.hpp" +#include "tapeserver/castor/tape/Constants.hpp" +#include "tapeserver/castor/tape/tapeserver/file/File.hpp" +#include "tapeserver/castor/tape/tapeserver/file/Structures.hpp" +#include "tapeserver/readtp/ReadtpCmd.hpp" +#include "tapeserver/readtp/ReadtpCmdLineArgs.hpp" +#include "tapeserver/readtp/TapeFseqRange.hpp" +#include "tapeserver/readtp/TapeFseqRangeListSequence.hpp" +#include "tapeserver/daemon/Tpconfig.hpp" +#include "tapeserver/castor/tape/tapeserver/daemon/Payload.hpp" +#include "mediachanger/LibrarySlotParser.hpp" +#include "disk/DiskFile.hpp" +#include "disk/RadosStriperPool.hpp" +#include "catalogue/TapeSearchCriteria.hpp" + + +namespace cta { +namespace tapeserver { +namespace readtp { + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +ReadtpCmd::ReadtpCmd(std::istream &inStream, std::ostream &outStream, + std::ostream &errStream, cta::log::StdoutLogger &log, cta::log::DummyLogger &dummyLog, + cta::mediachanger::MediaChangerFacade &mc): + CmdLineTool(inStream, outStream, errStream), + m_log(log), + m_dummyLog(dummyLog), + m_mc(mc), + m_useLbp(true), + m_nbSuccessReads(0), + m_nbFailedReads(0) { +} + +//------------------------------------------------------------------------------ +// destructor +//------------------------------------------------------------------------------ +ReadtpCmd::~ReadtpCmd() noexcept { +} + +//------------------------------------------------------------------------------ +// exceptionThrowingMain +//------------------------------------------------------------------------------ +int ReadtpCmd::exceptionThrowingMain(const int argc, char *const *const argv) { + const ReadtpCmdLineArgs cmdLineArgs(argc, argv); + if (cmdLineArgs.help) { + printUsage(m_out); + return 0; + } + + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", getUsername())); + params.push_back(cta::log::Param("tapeVid", cmdLineArgs.m_vid)); + m_log(cta::log::INFO, "Started", params); + + readAndSetConfiguration(getUsername(), cmdLineArgs); + + setProcessCapabilities("cap_sys_rawio+ep"); + + std::unique_ptr<castor::tape::tapeserver::drive::DriveInterface> drivePtr = createDrive(); + castor::tape::tapeserver::drive::DriveInterface &drive = *drivePtr.get(); + + if (!isDriveSupportLbp(drive)) { + m_log(cta::log::WARNING, "Drive does not support LBP", params); + m_driveSupportLbp = false; + } else { + m_driveSupportLbp = true; + }; + + mountTape(m_vid); + waitUntilTapeLoaded(drive, TAPE_LABEL_UNITREADY_TIMEOUT); + + int returnCode = 0; + try { + readTapeFiles(drive); + + } catch(cta::exception::Exception &ne) { + params.push_back(cta::log::Param("tapeReadError", ne.getMessage().str())); + m_log(cta::log::ERR, "Failed to read the tape", params); + returnCode = 1; + } + unloadTape(m_vid, drive); + dismountTape(m_vid); + + return returnCode; +} + +//------------------------------------------------------------------------------ +// readAndSetConfiguration +//------------------------------------------------------------------------------ +void ReadtpCmd::readAndSetConfiguration(const std::string &userName, const ReadtpCmdLineArgs &cmdLineArgs) { + m_vid = cmdLineArgs.m_vid; + m_fSeqRangeList = cmdLineArgs.m_fSeqRangeList; + m_xrootPrivateKeyPath = cmdLineArgs.m_xrootPrivateKeyPath; + m_userName = userName; + m_destinationFiles = readListFromFile(cmdLineArgs.m_destinationFileListURL); + cta::tape::daemon::Tpconfig tpConfig; + tpConfig = cta::tape::daemon::Tpconfig::parseFile(castor::tape::TPCONFIGPATH); + + if (tpConfig.empty()) { + cta::exception::Exception ex; + ex.getMessage() << "Unable to obtain drive info as TPCONFIG is empty"; + throw ex; + } + const auto &tpConfigLine = tpConfig.begin()->second.value(); + m_devFilename = tpConfigLine.devFilename; + m_rawLibrarySlot = tpConfigLine.rawLibrarySlot; + m_logicalLibrary = tpConfigLine.logicalLibrary; + m_unitName = tpConfigLine.unitName; + + const cta::rdbms::Login catalogueLogin = cta::rdbms::Login::parseFile(CATALOGUE_CONFIG_PATH); + const uint64_t nbConns = 1; + const uint64_t nbArchiveFileListingConns = 1; + + auto catalogueFactory = cta::catalogue::CatalogueFactoryFactory::create(m_dummyLog, // to supress catalogue output messages + catalogueLogin, nbConns, nbArchiveFileListingConns); + m_catalogue = catalogueFactory->create(); + + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("catalogueDbType", catalogueLogin.dbTypeToString(catalogueLogin.dbType))); + params.push_back(cta::log::Param("catalogueDatabase", catalogueLogin.database)); + params.push_back(cta::log::Param("catalogueUsername", catalogueLogin.username)); + params.push_back(cta::log::Param("devFilename", m_devFilename)); + params.push_back(cta::log::Param("rawLibrarySlot", m_rawLibrarySlot)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("unitName", m_unitName)); + m_log(cta::log::INFO, "Read configuration", params); +} + +//------------------------------------------------------------------------------ +// readListFromFile +//------------------------------------------------------------------------------ +std::list<std::string> ReadtpCmd::readListFromFile(const std::string &filename) const { + std::ifstream file(filename); + std::list<std::string> str_list; + if (file.fail()) { + throw std::runtime_error("Unable to open file " + filename); + } + + std::string line; + + while(std::getline(file, line)) { + // Strip out comments + auto pos = line.find('#'); + if(pos != std::string::npos) { + line.resize(pos); + } + + // Extract the list items + std::stringstream ss(line); + while(!ss.eof()) { + std::string item; + ss >> item; + // skip blank lines or lines consisting only of whitespace + if(item.empty()) continue; + + str_list.push_back(item); + } + } + return str_list; +} + + +//------------------------------------------------------------------------------ +// setProcessCapabilities +//------------------------------------------------------------------------------ +void ReadtpCmd::setProcessCapabilities(const std::string &capabilities) { + m_capUtils.setProcText(capabilities); + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("capabilities", capabilities)); + m_log(cta::log::DEBUG, "Set process capabilities", params); +} + +//------------------------------------------------------------------------------ +// createDrive +//------------------------------------------------------------------------------ +std::unique_ptr<castor::tape::tapeserver::drive::DriveInterface> + ReadtpCmd::createDrive() { + castor::tape::SCSI::DeviceVector dv(m_sysWrapper); + castor::tape::SCSI::DeviceInfo driveInfo = dv.findBySymlink(m_devFilename); + + // Instantiate the drive object + std::unique_ptr<castor::tape::tapeserver::drive::DriveInterface> + drive(castor::tape::tapeserver::drive::createDrive(driveInfo, m_sysWrapper)); + + if(NULL == drive.get()) { + cta::exception::Exception ex; + ex.getMessage() << "Failed to instantiate drive object"; + throw ex; + } + + return drive; +} + +//------------------------------------------------------------------------------ +// isDriveSupportLbp +//------------------------------------------------------------------------------ +bool ReadtpCmd::isDriveSupportLbp( + castor::tape::tapeserver::drive::DriveInterface &drive) const { + castor::tape::tapeserver::drive::deviceInfo devInfo = drive.getDeviceInfo(); + if (devInfo.isPIsupported) { //drive supports LBP + return true; + } else { + return false; + } +} + +//------------------------------------------------------------------------------ +// setLbpMode +//------------------------------------------------------------------------------ +void ReadtpCmd::setLbpMode( + castor::tape::tapeserver::drive::DriveInterface &drive) { + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", m_userName)); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + + if(m_useLbp) { + if (m_driveSupportLbp) { + // only crc32c lbp mode is supported + drive.enableCRC32CLogicalBlockProtectionReadWrite(); + m_log(cta::log::INFO, "Enabling LBP on drive", params); + } else { + m_useLbp = false; + drive.disableLogicalBlockProtection(); + m_log(cta::log::WARNING, "Disabling LBP on not supported drive", params); + } + } else { + drive.disableLogicalBlockProtection(); + m_log(cta::log::INFO, "Disabling LBP on drive", params); + } +} + +//------------------------------------------------------------------------------ +// mountTape +//------------------------------------------------------------------------------ +void ReadtpCmd::mountTape(const std::string &vid) { + std::unique_ptr<cta::mediachanger::LibrarySlot> librarySlotPtr; + librarySlotPtr.reset( + cta::mediachanger::LibrarySlotParser::parse(m_rawLibrarySlot)); + const cta::mediachanger::LibrarySlot &librarySlot = *librarySlotPtr.get(); + + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", m_userName)); + params.push_back(cta::log::Param("tapeVid", vid)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("librarySlot", librarySlot.str())); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + + m_log(cta::log::INFO, "Mounting tape", params); + m_mc.mountTapeReadOnly(vid, librarySlot); + if(cta::mediachanger::TAPE_LIBRARY_TYPE_MANUAL == librarySlot.getLibraryType()) { + m_log(cta::log::INFO, "Did not mount the tape because the media" + " changer is manual", params); + } else { + m_log(cta::log::INFO, "Mounted tape", params); + } +} + +//------------------------------------------------------------------------------ +// waitUntilTapeLoaded +//------------------------------------------------------------------------------ +void ReadtpCmd::waitUntilTapeLoaded( + castor::tape::tapeserver::drive::DriveInterface &drive, const int timeoutSecond) { + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", m_userName)); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + + try { + m_log(cta::log::INFO, "Loading tape", params); + drive.waitUntilReady(timeoutSecond); + m_log(cta::log::INFO, "Loaded tape", params); + } catch(cta::exception::Exception &ne) { + cta::exception::Exception ex; + ex.getMessage() << "Failed to wait for tape to be loaded: " << + ne.getMessage().str(); + throw ex; + } +} + +//Basic class representing a read job +class BasicRetrieveJob: public cta::RetrieveJob { +public: + BasicRetrieveJob() : cta::RetrieveJob(nullptr, + cta::common::dataStructures::RetrieveRequest(), + cta::common::dataStructures::ArchiveFile(), 1, + cta::PositioningMethod::ByFSeq) {} +}; + + +//------------------------------------------------------------------------------ +// getNextDestinationUrl +//------------------------------------------------------------------------------ +std::string ReadtpCmd::getNextDestinationUrl() { + if (m_destinationFiles.empty()) { + return "file:///dev/null"; + } else { + std::string ret = m_destinationFiles.front(); + m_destinationFiles.pop_front(); + return ret; + } +} + +//------------------------------------------------------------------------------ +// readTapeFiles +//------------------------------------------------------------------------------ +void ReadtpCmd::readTapeFiles( + castor::tape::tapeserver::drive::DriveInterface &drive) { + cta::disk::RadosStriperPool striperPool; + cta::disk::DiskFileFactory fileFactory(m_xrootPrivateKeyPath, 0, striperPool); + + catalogue::TapeSearchCriteria searchCriteria; + searchCriteria.vid = m_vid; + + auto tapeList = m_catalogue->getTapes(searchCriteria); + if (tapeList.empty()) { + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", getUsername())); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + m_log(cta::log::ERR, "Failed to get tape from catalogue", params); + return; + } + auto tape = tapeList.front(); + + TapeFseqRangeListSequence fSeqRangeListSequence(&m_fSeqRangeList); + std::string destinationFile = getNextDestinationUrl(); + uint64_t fSeq; + while (fSeqRangeListSequence.hasMore()) { + try { + fSeq = fSeqRangeListSequence.next(); + if (fSeq > tape.lastFSeq) { + break; //reached end of tape + } + std::unique_ptr<cta::disk::WriteFile> wfptr; + wfptr.reset(fileFactory.createWriteFile(destinationFile)); + cta::disk::WriteFile &wf = *wfptr.get(); + readTapeFile(drive, fSeq, wf); + m_nbSuccessReads++; // if readTapeFile returns, file was read successfully + destinationFile = getNextDestinationUrl(); + } catch (tapeserver::readtp::NoSuchFSeqException) { + //Do nothing + } catch(exception::Exception &ne) { + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", getUsername())); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("destinationFile", destinationFile)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + params.push_back(cta::log::Param("fSeq", fSeq)); + params.push_back(cta::log::Param("tapeReadError", ne.getMessage().str())); + m_log(cta::log::ERR, "Failed to read file from tape", params); + m_nbFailedReads++; + } + } + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", getUsername())); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + params.push_back(cta::log::Param("nbReads", m_nbSuccessReads + m_nbFailedReads)); + params.push_back(cta::log::Param("nbSuccessfullReads", m_nbSuccessReads)); + params.push_back(cta::log::Param("nbFailedReads", m_nbFailedReads)); + + m_log(cta::log::INFO, "Finished reading tape", params); + +} + +//------------------------------------------------------------------------------ +// readTapeFile +//------------------------------------------------------------------------------ +void ReadtpCmd::readTapeFile( + castor::tape::tapeserver::drive::DriveInterface &drive, const uint64_t &fSeq, cta::disk::WriteFile &wf) { + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", m_userName)); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("fSeq", fSeq)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + params.push_back(cta::log::Param("destinationURL", wf.URL())); + + castor::tape::tapeserver::daemon::VolumeInfo volInfo; + volInfo.vid=m_vid; + volInfo.nbFiles = 0; + volInfo.mountType = cta::common::dataStructures::MountType::Retrieve; + castor::tape::tapeFile::ReadSession rs(drive, volInfo, m_useLbp); + + catalogue::TapeFileSearchCriteria searchCriteria; + searchCriteria.vid = m_vid; + searchCriteria.fSeq = fSeq; + auto itor = m_catalogue->getArchiveFilesItor(searchCriteria); + + if (!itor.hasMore()) { + throw tapeserver::readtp::NoSuchFSeqException(); + } + + m_log(cta::log::INFO, "Reading file from tape", params); + + const auto archiveFile = itor.next(); + + BasicRetrieveJob fileToRecall; + fileToRecall.retrieveRequest.archiveFileID = archiveFile.archiveFileID; + fileToRecall.selectedCopyNb = 0; + fileToRecall.archiveFile.tapeFiles.push_back(cta::common::dataStructures::TapeFile()); + fileToRecall.selectedTapeFile().fSeq = fSeq; + fileToRecall.positioningMethod = cta::PositioningMethod::ByFSeq; + + castor::tape::tapeFile::ReadFile rf(&rs, fileToRecall); + auto checksum_adler32 = castor::tape::tapeserver::daemon::Payload::zeroAdler32(); + const size_t buffer_size = 1 * 1024 * 1024 * 1024; //1Gb + size_t read_data_size = 0; + auto payload = new castor::tape::tapeserver::daemon::Payload(buffer_size); //allocate one gigabyte buffer + try { + while(1) { + if (payload->remainingFreeSpace() <= rf.getBlockSize()) { + //buffer is full, flush to file and update checksum + read_data_size += payload->size(); + checksum_adler32 = payload->adler32(checksum_adler32); + payload->write(wf); + payload->reset(); + } + payload->append(rf); + } + } catch (cta::exception::EndOfFile ex) { + //File completely read + } + read_data_size += payload->size(); + checksum_adler32 = payload->adler32(checksum_adler32); + payload->write(wf); + auto cb = cta::checksum::ChecksumBlob(cta::checksum::ChecksumType::ADLER32, checksum_adler32); + + archiveFile.checksumBlob.validate(cb); //exception thrown if checksums differ + + params.push_back(cta::log::Param("checksumType", "ADLER32")); + std::stringstream sstream; + sstream << std::hex << checksum_adler32; + params.push_back(cta::log::Param("checksumValue", "0x" + sstream.str())); + params.push_back(cta::log::Param("readFileSize", read_data_size)); + m_log(cta::log::INFO, "Read file from tape successfully", params); +} + +//------------------------------------------------------------------------------ +// unloadTape +//------------------------------------------------------------------------------ +void ReadtpCmd::unloadTape( + const std::string &vid, castor::tape::tapeserver::drive::DriveInterface &drive) { + std::unique_ptr<cta::mediachanger::LibrarySlot> librarySlotPtr; + librarySlotPtr.reset( + cta::mediachanger::LibrarySlotParser::parse(m_rawLibrarySlot)); + const cta::mediachanger::LibrarySlot &librarySlot = *librarySlotPtr.get(); + + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", m_userName)); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + + // We implement the same policy as with the tape sessions: + // if the librarySlot parameter is "manual", do nothing. + if(cta::mediachanger::TAPE_LIBRARY_TYPE_MANUAL == librarySlot.getLibraryType()) { + m_log(cta::log::INFO, "Not unloading tape because media changer is" + " manual", params); + return; + } + try { + m_log(cta::log::INFO, "Unloading tape", params); + drive.unloadTape(); + m_log(cta::log::INFO, "Unloaded tape", params); + } catch (cta::exception::Exception &ne) { + cta::exception::Exception ex; + ex.getMessage() << "Failed to unload tape: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// dismountTape +//------------------------------------------------------------------------------ +void ReadtpCmd::dismountTape(const std::string &vid) { + std::unique_ptr<cta::mediachanger::LibrarySlot> librarySlotPtr; + librarySlotPtr.reset( + cta::mediachanger::LibrarySlotParser::parse(m_rawLibrarySlot)); + const cta::mediachanger::LibrarySlot &librarySlot = *librarySlotPtr.get(); + + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", m_userName)); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("librarySlot", librarySlot.str())); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + + try { + m_log(cta::log::INFO, "Dismounting tape", params); + m_mc.dismountTape(vid, librarySlot); + const bool dismountWasManual = cta::mediachanger::TAPE_LIBRARY_TYPE_MANUAL == + librarySlot.getLibraryType(); + if(dismountWasManual) { + m_log(cta::log::INFO, "Did not dismount tape because media" + " changer is manual", params); + } else { + m_log(cta::log::INFO, "Dismounted tape", params); + } + } catch(cta::exception::Exception &ne) { + cta::exception::Exception ex; + ex.getMessage() << "Failed to dismount tape: " << + ne.getMessage().str(); + throw ex; + } +} + +//------------------------------------------------------------------------------ +// rewindDrive +//------------------------------------------------------------------------------ +void ReadtpCmd::rewindDrive( + castor::tape::tapeserver::drive::DriveInterface &drive) { + std::list<cta::log::Param> params; + params.push_back(cta::log::Param("userName", m_userName)); + params.push_back(cta::log::Param("tapeVid", m_vid)); + params.push_back(cta::log::Param("tapeDrive", m_unitName)); + params.push_back(cta::log::Param("logicalLibrary", m_logicalLibrary)); + params.push_back(cta::log::Param("useLbp",boolToStr(m_useLbp))); + params.push_back(cta::log::Param("driveSupportLbp",boolToStr(m_driveSupportLbp))); + + m_log(cta::log::INFO, "Rewinding tape", params); + drive.rewind(); + m_log(cta::log::INFO, "Successfully rewound tape", params); +} + +//------------------------------------------------------------------------------ +// printUsage +//------------------------------------------------------------------------------ +void ReadtpCmd::printUsage(std::ostream &os) { + ReadtpCmdLineArgs::printUsage(os); +} + +//------------------------------------------------------------------------------ +// boolToStr +//------------------------------------------------------------------------------ +const char *ReadtpCmd::boolToStr( + const bool value) { + return value ? "true" : "false"; +} + +} // namespace readtp +} // namespace tapeserver +} // namespace cta \ No newline at end of file diff --git a/tapeserver/readtp/ReadtpCmd.hpp b/tapeserver/readtp/ReadtpCmd.hpp new file mode 100644 index 0000000000000000000000000000000000000000..75f8d79fa07ff3a6ab93841556d682c33fc95f9c --- /dev/null +++ b/tapeserver/readtp/ReadtpCmd.hpp @@ -0,0 +1,311 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "common/log/StdoutLogger.hpp" +#include "common/log/DummyLogger.hpp" +#include "common/log/LogContext.hpp" +#include "common/processCap/ProcessCap.hpp" +#include "tapeserver/readtp/ReadtpCmdLineArgs.hpp" +#include "tapeserver/castor/tape/tapeserver/drive/DriveInterface.hpp" +#include "tapeserver/castor/tape/tapeserver/drive/DriveGeneric.hpp" +#include "tapeserver/castor/tape/tapeserver/daemon/EncryptionControl.hpp" +#include "tapeserver/daemon/Tpconfig.hpp" +#include "tapeserver/readtp/CmdLineTool.hpp" +#include "tapeserver/readtp/TapeFseqRange.hpp" +#include "tapeserver/readtp/TapeFseqRangeListSequence.hpp" +#include "catalogue/CatalogueFactoryFactory.hpp" +#include "mediachanger/MediaChangerFacade.hpp" +#include "disk/DiskFile.hpp" + +#include <memory> + +namespace cta { +namespace tapeserver { +namespace readtp { + +/** + * Command-line tool for reading files from a CTA tape. + */ +class ReadtpCmd: public CmdLineTool { +public: + + /** + * Constructor. + * + * @param inStream Standard input stream. + * @param outStream Standard output stream. + * @param errStream Standard error stream. + * @param log The object representing the API of the CTA logging system. + * @param mc Interface to the media changer. + */ + ReadtpCmd(std::istream &inStream, std::ostream &outStream, + std::ostream &errStream, cta::log::StdoutLogger &log, + cta::log::DummyLogger &dummyLog, + cta::mediachanger::MediaChangerFacade &mc); + + /** + * Destructor. + */ + ~ReadtpCmd() noexcept; + +private: + + /** + * An exception throwing version of main(). + * + * @param argc The number of command-line arguments including the program name. + * @param argv The command-line arguments. + * @return The exit value of the program. + */ + int exceptionThrowingMain(const int argc, char *const *const argv) override; + + /** + * Prints the usage message of the command-line tool. + * + * @param os The output stream to which the usage message is to be printed. + */ + void printUsage(std::ostream &os) override; + + /** + * Sets internal configuration parameters to be used for reading. + * It reads drive and library parameters from /etc/cta/TPCONFIG and catalogue + * login parameters from /etc/cta/cta-catalogue.conf. + * + * @param username The name of the user running the command-line tool. + * @param cmdLineArgs The arguments parsed from the command line. + */ + void readAndSetConfiguration(const std::string &userName, const ReadtpCmdLineArgs &cmdLineArgs); + + /** + * Reads a file line by line, strips comments and returns a list of the file lines. + * + * @param filename The name of the file to be read. + * @return A list of line strings after stripping comments. + */ + std::list<std::string> readListFromFile(const std::string &filename) const; + + /** + * Returns the next destination file URL, or file:///dev/null if all destination files have been used. + * + * @return The URL of the next destination file. + */ + std::string getNextDestinationUrl(); + + /** + * Sets the capabilities of the process and logs the result. + * + * @param capabilities The string representation of the capabilities. + */ + void setProcessCapabilities(const std::string &capabilities); + + /** + * Returns a Drive object representing the tape drive to be used to read + * the tape. + * + * @return The drive object. + */ + std::unique_ptr<castor::tape::tapeserver::drive::DriveInterface> createDrive(); + + /** + * Detects if the drive supports the logical block protection. + * + * @param drive The tape drive. + * @return The boolean value true if the drive supports LBP or false otherwise. + */ + bool isDriveSupportLbp(castor::tape::tapeserver::drive::DriveInterface &drive) const; + + /** + * Sets the logical block protection mode on the drive + * depending on useLbp and driveSupportLbp parameters. This method needs to + * be used to avoid exceptions in setLbp if drive does not support LBP (mhvtl). + * + * @param drive The tape drive. + */ + void setLbpMode(castor::tape::tapeserver::drive::DriveInterface &drive); + + /** + * Mounts the tape to be read. + * @param vid The volume identifier of the tape to be mounted. + */ + void mountTape(const std::string &vid); + + /** + * Waits for the tape to be loaded into the tape drive. + * + * @param drive Object representing the drive hardware. + * @param timeoutSecond The number of seconds to wait for the tape to be + * loaded into the tape drive. + */ + void waitUntilTapeLoaded(castor::tape::tapeserver::drive::DriveInterface &drive, + const int timeoutSecond); + + /** + * Read the files requested from tape + * + * @param drive Object representing the drive hardware. + */ + void readTapeFiles(castor::tape::tapeserver::drive::DriveInterface &drive); + + /** + * Read a specific file from tape + * @param drive Object representing the drive hardware. + * @param fSeq The tape file fSeq. + */ + void readTapeFile(castor::tape::tapeserver::drive::DriveInterface &drive, const uint64_t &fSeq, + cta::disk::WriteFile &wf); + + + /** + * Unloads the specified tape from the specified tape drive. + * + * @param vid The volume identifier of the tape to be unloaded. Please note + * that the value of this field is only used for logging purposes. + * @param drive The tape drive. + */ + void unloadTape(const std::string &vid, castor::tape::tapeserver::drive::DriveInterface &drive); + + /** + * Dismounts the specified tape. + * + * @param vid The volume identifier of the tape to be dismounted. + */ + void dismountTape(const std::string &vid); + + /** + * Rewinds the specified tape drive. + * + * @param drive The tape drive. + */ + void rewindDrive(castor::tape::tapeserver::drive::DriveInterface &drive); + + /** + * Returns the string representation of the specified boolean value. + * + * @param value The boolean value. + * @return The string representation. + */ + const char *boolToStr(const bool value); + + /** + * The object representing the API of the CTA logging system. + */ + cta::log::StdoutLogger &m_log; + +/** + *Dummy logger for the catalogue + */ + cta::log::DummyLogger &m_dummyLog; + + /** + * Hard coded path for the catalogue login configuration. + */ + const std::string CATALOGUE_CONFIG_PATH = "/etc/cta/cta-catalogue.conf"; + + /** + * Unique pointer to the catalogue interface; + */ + std::unique_ptr<cta::catalogue::Catalogue> m_catalogue; + + /** + * Object providing utilities for working UNIX capabilities. + */ + cta::server::ProcessCap m_capUtils; + + /** + * The system wrapper used to find the device and instantiate the drive object. + */ + castor::tape::System::realWrapper m_sysWrapper; + + /** + * The filename of the device file of the tape drive. + */ + std::string m_devFilename; + + /** + * The slot in the tape library that contains the tape drive (string encoded). + */ + std::string m_rawLibrarySlot; + + /** + * The logical library of the tape drive. + */ + std::string m_logicalLibrary; + + /** + * The unit name of the tape drive. + */ + std::string m_unitName; + + /** + * The name of the user running the command-line tool. + */ + std::string m_userName; + + /** + * The tape VID to read. + */ + std::string m_vid; + + /** + * Path to the xroot private key file. + */ + std::string m_xrootPrivateKeyPath; + + /** + * The iterator of destination urls the data read is sent to + */ + std::list<std::string> m_destinationFiles; + + /** + * The file fSeq to read. + */ + TapeFseqRangeList m_fSeqRangeList; + + /** + * The object representing the media changer. + */ + cta::mediachanger::MediaChangerFacade &m_mc; + + /** + * The boolean variable which determinate logical block protection usage by + * readtp commands. Hard coded when we create the class. + */ + bool m_useLbp; + + /** + * The boolean variable to store if drive support LBP. + */ + bool m_driveSupportLbp; + + /** + * Number of files read successsfully. + */ + uint64_t m_nbSuccessReads; + + /** + * Number of failed reads. + */ + uint64_t m_nbFailedReads; +}; // class ReadtpCmd + +CTA_GENERATE_EXCEPTION_CLASS(NoSuchFSeqException); + +} // namespace readtp +} // namespace tapeserver +} // namespace cta \ No newline at end of file diff --git a/tapeserver/readtp/ReadtpCmdLineArgs.cpp b/tapeserver/readtp/ReadtpCmdLineArgs.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3f409ffc2bd637f41d0fffab3d9ad145849112e9 --- /dev/null +++ b/tapeserver/readtp/ReadtpCmdLineArgs.cpp @@ -0,0 +1,133 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "tapeserver/readtp/ReadtpCmdLineArgs.hpp" +#include "tapeserver/readtp/TapeFseqSequenceParser.hpp" +#include "common/exception/CommandLineNotParsed.hpp" +#include "common/utils/utils.hpp" +#include "common/Constants.hpp" + +#include <getopt.h> +#include <ostream> + +#include <string.h> + +namespace cta { +namespace tapeserver { +namespace readtp { + + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +ReadtpCmdLineArgs::ReadtpCmdLineArgs(const int argc, char *const *const argv): + help(false), m_vid(""), m_destinationFileListURL(""), m_xrootPrivateKeyPath("") { + if (argc < 3) { + help = true; + return; + } + if ((strlen(argv[1])) > CA_MAXVIDLEN) { + exception::CommandLineNotParsed ex; + ex.getMessage() << "The vid is too long"; + throw ex; + } + m_vid = std::string(argv[1]); + utils::toUpper(m_vid); + + m_fSeqRangeList = TapeFileSequenceParser::parse(argv[2]); + + static struct option longopts[] = { + {"destination_files", required_argument, NULL, 'f'}, + {"xroot_private_key", required_argument, NULL, 'p'}, + {"help", no_argument, NULL, 'h'}, + {NULL , 0, NULL, 0} + }; + + opterr = 0; + int opt = 0; + int opt_index = 3; + + while ((opt = getopt_long(argc, argv, ":d:f:p:h", longopts, &opt_index)) != -1) { + switch(opt) { + case 'f': + m_destinationFileListURL = std::string(optarg); + break; + case 'p': + m_xrootPrivateKeyPath = std::string(optarg); + break; + case 'h': + help = true; + break; + case ':': // Missing parameter + { + exception::CommandLineNotParsed ex; + ex.getMessage() << "The -" << (char)optopt << " option requires a parameter"; + throw ex; + } + case '?': // Unknown option + { + exception::CommandLineNotParsed ex; + if(0 == optopt) { + ex.getMessage() << "Unknown command-line option"; + } else { + ex.getMessage() << "Unknown command-line option: -" << (char)optopt; + } + throw ex; + } + default: + { + exception::CommandLineNotParsed ex; + ex.getMessage() << + "getopt_long returned the following unknown value: 0x" << + std::hex << (int)opt; + throw ex; + } + } // switch(opt) + } // while getopt_long() + + if (m_destinationFileListURL.empty()) { + m_destinationFileListURL = "/dev/null"; // Equivalent to an empty file + } +} + + +//------------------------------------------------------------------------------ +// printUsage +//------------------------------------------------------------------------------ +void ReadtpCmdLineArgs::printUsage(std::ostream &os) { + os << + "Usage:" << std::endl << + " cta-readtp <VID> <SEQUENCE> [options]" << std::endl << + "Where:" << std::endl << + " <VID> The VID of the tape to be read" << std::endl << + " <SEQUENCE> A sequence of tape file sequence numbers. The syntax to be used is:" << std::endl << + " f1-f2 Files f1 to f2 inclusive" << std::endl << + " f1- Files f1 to the last file on the tape" << std::endl << + " f1-f2,f4,f6- A series of non-consecutive ranges of files" << std::endl << + "Options:" <<std::endl << + " -h, --help Print this help message and exit." << std::endl << + " -p, --xroot_private_key <KEY PATH> Path to the xroot private key file. Necessary if" << std::endl << + " read files are to be written using xroot." << std::endl << + " -f, --destination_files <FILE URL> URL to file containing a list of destination files." << std::endl << + " If not set, all data read is written to file:///dev/null" << std::endl << + " If there are less destination files than read files, the remaining" << std::endl << + " files read will be written to file:///dev/null." << std::endl; +} + +} // namespace readtp +} // namespace tapeserver +} // namespace cta \ No newline at end of file diff --git a/tapeserver/readtp/ReadtpCmdLineArgs.hpp b/tapeserver/readtp/ReadtpCmdLineArgs.hpp new file mode 100644 index 0000000000000000000000000000000000000000..e62cea3bb819ef2ca1e3f816b61efe4ceeb42ce0 --- /dev/null +++ b/tapeserver/readtp/ReadtpCmdLineArgs.hpp @@ -0,0 +1,77 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "tapeserver/readtp/TapeFseqRangeListSequence.hpp" + +#include <string> + +namespace cta { +namespace tapeserver { +namespace readtp { + +/** + * Structure to store the command-line arguments of the command-line tool + * named cta-readtp. + */ +struct ReadtpCmdLineArgs { + /** + * True if the usage message should be printed. + */ + bool help; + + /** + * The tape VID to read. + */ + std::string m_vid; + + /** + * Sequence of file fSeqs to read. + */ + TapeFseqRangeList m_fSeqRangeList; + + /** + * The destination file list url. + */ + std::string m_destinationFileListURL; + + /** + * Path to the xroot private key file. + */ + std::string m_xrootPrivateKeyPath; + + /** + * Constructor that parses the specified command-line arguments. + * + * @param argc The number of command-line arguments including the name of the + * executable. + * @param argv The vector of command-line arguments. + */ + ReadtpCmdLineArgs(const int argc, char *const *const argv); + + /** + * Prints the usage message of the command-line tool. + * + * @param os The output stream to which the usage message is to be printed. + */ + static void printUsage(std::ostream &os); +}; // class ReadtpCmdLineArgs + +} // namespace readtp +} // namespace tapeserver +} // namespace cta diff --git a/tapeserver/readtp/ReadtpCmdMain.cpp b/tapeserver/readtp/ReadtpCmdMain.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4ec024ccfcdcbeea016e291681647f9b8199dd8c --- /dev/null +++ b/tapeserver/readtp/ReadtpCmdMain.cpp @@ -0,0 +1,40 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "tapeserver/readtp/ReadtpCmd.hpp" +#include <iostream> + +//------------------------------------------------------------------------------ +// main +//------------------------------------------------------------------------------ +int main(const int argc, char *const *const argv) { + char buf[256]; + std::string hostName; + if(gethostname(buf, sizeof(buf))) { + hostName = "UNKNOWN"; + } else { + buf[sizeof(buf) - 1] = '\0'; + hostName = buf; + } + cta::log::StdoutLogger log(hostName, "cta-readtp"); + cta::log::DummyLogger dummyLog("dummy", "dummy"); + cta::mediachanger::MediaChangerFacade mc(log); + + cta::tapeserver::readtp::ReadtpCmd cmd(std::cin, std::cout, std::cerr, log, dummyLog, mc); + return cmd.main(argc, argv); +} \ No newline at end of file diff --git a/tapeserver/readtp/TapeFseqRange.cpp b/tapeserver/readtp/TapeFseqRange.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81cd07918bdfffe6536ab688f2201c4bc822d733 --- /dev/null +++ b/tapeserver/readtp/TapeFseqRange.cpp @@ -0,0 +1,152 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "tapeserver/readtp/TapeFseqRange.hpp" +#include "common/exception/InvalidArgument.hpp" + +#include <getopt.h> +#include <ostream> + +#include <string.h> + +namespace cta { +namespace tapeserver { +namespace readtp { + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +TapeFseqRange::TapeFseqRange() throw() { + + reset(); +} + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +TapeFseqRange::TapeFseqRange(const uint32_t lower, const uint32_t upper) { + + reset(lower, upper); +} + +//------------------------------------------------------------------------------ +// reset +//------------------------------------------------------------------------------ +void TapeFseqRange::reset() throw() { + m_isEmpty = true; + m_lower = 0; // Ignored + m_upper = 0; // Ignored +} + + +//------------------------------------------------------------------------------ +// reset +//------------------------------------------------------------------------------ +void TapeFseqRange::reset(const uint32_t lower, + const uint32_t upper) { + + if(lower == 0) { + exception::InvalidArgument ex; + + ex.getMessage() << "Lower boundary must not be zero"; + throw ex; + } + + // If the upper boundary is not 0 meaning infinity and the lower boundary is + // greater than the upper boundary + if(upper != 0 && lower > upper) { + exception::InvalidArgument ex; + + ex.getMessage() << + "Lower boundary must be less than or equal to the upper boundary" + ": lower=" << lower << " upper=" << upper; + + throw ex; + } + + m_isEmpty = false; + m_lower = lower; + m_upper = upper; +} + + +//------------------------------------------------------------------------------ +// isEmpty +//------------------------------------------------------------------------------ +bool TapeFseqRange::isEmpty() const throw() { + return m_isEmpty; +} + +//------------------------------------------------------------------------------ +// lower +//------------------------------------------------------------------------------ +uint32_t TapeFseqRange::lower() const throw() { + + return m_isEmpty ? 0 : m_lower; +} + +//------------------------------------------------------------------------------ +// upper +//------------------------------------------------------------------------------ +uint32_t TapeFseqRange::upper() const throw() { + + return m_isEmpty ? 0 : m_upper; +} + +//------------------------------------------------------------------------------ +// size +//------------------------------------------------------------------------------ +uint32_t TapeFseqRange::size() const throw() { + + return m_isEmpty || m_upper == 0 ? 0 : m_upper - m_lower + 1; +} + +} // namespace readtp +} // namespace tapeserver +} // namespace cta + +//------------------------------------------------------------------------------ +// ostream << operator for cta::tapeserver::readtp::TapeFseqRange +//------------------------------------------------------------------------------ +std::ostream &operator<<(std::ostream &os, + const cta::tapeserver::readtp::TapeFseqRange &value) { + + if(value.isEmpty()) { + os << "EMPTY"; + } else { + uint32_t lower = 0; + uint32_t upper = 0; + + try { + lower = value.lower(); + upper = value.upper(); + + os << lower << "-"; + + // An upper value of 0 means END of tape + if(upper !=0) { + os << upper; + } else { + os << "END"; + } + } catch(cta::exception::Exception &ex) { + os << "ERROR"; + } + } + + return os; +} diff --git a/tapeserver/readtp/TapeFseqRange.hpp b/tapeserver/readtp/TapeFseqRange.hpp new file mode 100644 index 0000000000000000000000000000000000000000..35d903cc7faeea222986baf5abef2f63709c9633 --- /dev/null +++ b/tapeserver/readtp/TapeFseqRange.hpp @@ -0,0 +1,129 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include <string> +#include <ostream> + +namespace cta { +namespace tapeserver { +namespace readtp { + +/** + * A range of tape file sequence numbers specified by an inclusive lower + * boundary and an inclusive upper boundary. + */ +class TapeFseqRange { + +public: + + /** + * Constructor. + * + * Constructs an empty range. + */ + TapeFseqRange() throw(); + + /** + * Constructor. + * + * Constructs a range with the specified inclusive lower and upper + * boundaries. An upper boundary of 0 means infinity. + * + * Throws an InvalidArgument exception if either the lower boundary is 0 + * or if the lower boundary is greater than the upper boundary. + * + * @param lower The inclusive lower bound of the range. + * @param upper The inclusive upper bound of the range. + */ + TapeFseqRange(const uint32_t lower, const uint32_t upper) + ; + + /** + * Resets the range to be an empty range. + */ + void reset() throw(); + + /** + * Resets the range to be a finite range with the specified inclusive lower + * and upper boundaries. + * + * Throws an InvalidArgument exception if either the lower boundary is 0 + * or if the lower boundary is greater than the upper boundary. + * + * @param lower The inclusive lower bound of the range. + * @param upper The inclusive upper bound of the range. + */ + void reset(const uint32_t lower, const uint32_t upper) + ; + + /** + * Returns true if the range is empty. + */ + bool isEmpty() const throw(); + + /** + * Returns the inclusive lower bound of the range or 0 if the range is empty. + */ + uint32_t lower() const throw(); + + /** + * Returns the inclusive upper bound of the range. If the range is finite, + * then a value greater than 0 is returned. If the range is either empty or + * infinite then 0 is returned. The method isEmpty() or a lower() return + * value of 0 can be used to distinguish between the two cases when upper() + * returns 0. + */ + uint32_t upper() const throw(); + + /** + * Returns the size of the range. An empty or infinite range returns 0. + * The method isEmpty() or a lower() return value of 0 can be used to + * distinguish between the two cases when size() returns 0. + */ + uint32_t size() const throw(); + + +private: + + /** + * True if this range is empty, else false. + */ + bool m_isEmpty; + + /** + * The inclusive lower bound of the range. + */ + uint32_t m_lower; + + /** + * The inclusive upper bound of the range. A value of 0 means infinity. + */ + uint32_t m_upper; +}; + +} // namespace readtp +} // namespace tapeserver +} // namespace cta + +/** + * ostream << operator for cta::tapeserver::readtp::TapeFseqRange + */ +std::ostream &operator<<(std::ostream &os, + const cta::tapeserver::readtp::TapeFseqRange &value); + diff --git a/tapeserver/readtp/TapeFseqRangeListSequence.cpp b/tapeserver/readtp/TapeFseqRangeListSequence.cpp new file mode 100644 index 0000000000000000000000000000000000000000..479ffd6cb259b051e73dca8b5d5ba3a9c4d7c153 --- /dev/null +++ b/tapeserver/readtp/TapeFseqRangeListSequence.cpp @@ -0,0 +1,174 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "tapeserver/readtp/TapeFseqRange.hpp" +#include "tapeserver/readtp/TapeFseqRangeListSequence.hpp" +#include "common/exception/InvalidArgument.hpp" +#include "common/exception/Exception.hpp" + +#include <getopt.h> +#include <ostream> + +#include <list> +#include <errno.h> + +namespace cta { +namespace tapeserver { +namespace readtp { + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +TapeFseqRangeListSequence::TapeFseqRangeListSequence() + { + reset(NULL); +} + + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +TapeFseqRangeListSequence::TapeFseqRangeListSequence( + const TapeFseqRangeList *const list) { + reset(list); +} + + +//------------------------------------------------------------------------------ +// reset +//------------------------------------------------------------------------------ +void TapeFseqRangeListSequence::reset( + const TapeFseqRangeList *const list) { + m_list = list; + + if(m_list == NULL) { + m_isFinite = true; + m_totalSize = 0; + } else { + m_rangeItor = list->begin(); + m_nbSequence = (*(list->begin())); + + // Determine the values of m_isFinite and m_totalSize + m_isFinite = true; // Initial guess + m_totalSize = 0; // Initial guess + for(TapeFseqRangeList::const_iterator itor=list->begin(); + itor != list->end(); itor++) { + const TapeFseqRange &range = *itor; + + // If upper bound of range is infinity + if(range.upper() == 0) { + m_isFinite = false; + m_totalSize = 0; + + // No need to continue counting + break; + + // Else the upper bound is finite + } else { + m_totalSize += range.size(); + } + } + } +} + + +//------------------------------------------------------------------------------ +// hasMore +//------------------------------------------------------------------------------ +bool TapeFseqRangeListSequence::hasMore() const throw() { + if(m_list != NULL) { + return m_nbSequence.hasMore(); + } else { + return false; + } +} + + +//------------------------------------------------------------------------------ +// next +//------------------------------------------------------------------------------ +uint32_t TapeFseqRangeListSequence::next() + { + + if(!hasMore()) { + exception::Exception ex; + + ex.getMessage() + << "Invalid operation: Sequence::next() called after end of sequence"; + + throw ex; + } + + uint32_t tmp = m_nbSequence.next(); + + // If the end of the current range sequence has been reached + if(!m_nbSequence.hasMore()) { + + // Move on to the next if there is one + m_rangeItor++; + if(m_rangeItor != m_list->end()) { + m_nbSequence = *m_rangeItor; + } + } + + return tmp; +} + + +//------------------------------------------------------------------------------ +// isFinite +//------------------------------------------------------------------------------ +bool TapeFseqRangeListSequence::isFinite() const throw() { + return m_isFinite; +} + + +//------------------------------------------------------------------------------ +// totalSize +//------------------------------------------------------------------------------ +uint32_t TapeFseqRangeListSequence::totalSize() + const throw() { + return m_totalSize; +} + +} // namespace readtp +} // namespace tapeserver +} // namespace cta + +//------------------------------------------------------------------------------ +// ostream << operator for castor::tape::tpcp::TapeFseqRangeList +//------------------------------------------------------------------------------ +std::ostream &operator<<(std::ostream &os, + const cta::tapeserver::readtp::TapeFseqRangeList &value) { + + os << '{'; + + for(cta::tapeserver::readtp::TapeFseqRangeList::const_iterator itor = + value.begin(); itor != value.end(); itor++) { + + // Write a separating comma if not the first item in the list + if(itor!=value.begin()) { + os << ","; + } + + os << *itor; + } + + os << '}'; + + return os; +} diff --git a/tapeserver/readtp/TapeFseqRangeListSequence.hpp b/tapeserver/readtp/TapeFseqRangeListSequence.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7ce698f802b5ddb594b81faf193b14f227aeba77 --- /dev/null +++ b/tapeserver/readtp/TapeFseqRangeListSequence.hpp @@ -0,0 +1,135 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "TapeFseqRange.hpp" +#include "TapeFseqRangeSequence.hpp" + +#include <list> +#include <ostream> + +namespace cta { +namespace tapeserver { +namespace readtp { + +/** + * A list of tape file sequence ranges. + */ +class TapeFseqRangeList: public std::list<TapeFseqRange> { +}; // class TapeFseqRangeList + +/** + * Generates a sequence of tape file sequence numbers from a list of tape file + * sequence ranges. + */ +class TapeFseqRangeListSequence { +public: + + /** + * Constructor. + * + * Creates an empty sequence, in other word hasMore() will always return + * false. + */ + TapeFseqRangeListSequence() ; + + /** + * Constructor. + * + * @param list The list of tape file sequence ranges from which the sequence + * of tape file sequence numbers is to be generated. + */ + TapeFseqRangeListSequence(const TapeFseqRangeList *const list) + ; + + /** + * Resets the sequence. + * + * @param list The list of tape file sequence ranges from which the sequence + * of tape file sequence numbers is to be generated. + */ + void reset(const TapeFseqRangeList *const list) + ; + + /** + * Returns true if there is another tape file sequence number in the + * sequence. + */ + bool hasMore() const throw(); + + /** + * Returns the next tape file sequence number in the sequence, or throws an + * exception if there isn't one. + */ + uint32_t next() ; + + /** + * Returns true if the sequence is finite, else false if it is infinite. + */ + bool isFinite() const throw(); + + /** + * Returns the total number of values the sequence could ever generate. The + * value returned by this method is not affected by calls to next(). This + * method returns 0 if the total number of values is 0 or infinity. The + * isFinite() method can be used to distinguish between the two cases. + */ + uint32_t totalSize() const throw(); + + +private: + + /** + * The list of tape file sequence ranges. + */ + const TapeFseqRangeList *m_list; + + /** + * Iterator pointing to the current range of tape file sequence numbers. + */ + TapeFseqRangeList::const_iterator m_rangeItor; + + /** + * True if the sequence is finite, else false if it is infinite. + */ + bool m_isFinite; + + /** + * The total number of values the sequence could ever generate. The + * value returned by this method is not affected by calls to next(). This + * method returns 0 if the total number of values is 0 or infinity. The + * isFinite() method can be used to distinguish between the two cases. + */ + uint32_t m_totalSize; + + /** + * The current sequence of the tape file sequence numbers. + */ + TapeFseqRangeSequence m_nbSequence; + +}; // class TapeFseqRangeListSequence + +} // namespace readtp +} // namespace tapeserver +} // namespace cta + +/** + * ostream << operator for cta::tapeserver::readtp::TapeFseqRangeList + */ +std::ostream &operator<<(std::ostream &os, + const cta::tapeserver::readtp::TapeFseqRangeList &value); diff --git a/tapeserver/readtp/TapeFseqRangeSequence.cpp b/tapeserver/readtp/TapeFseqRangeSequence.cpp new file mode 100644 index 0000000000000000000000000000000000000000..de7c65ed20013bab3fc956b1f18c964edd956855 --- /dev/null +++ b/tapeserver/readtp/TapeFseqRangeSequence.cpp @@ -0,0 +1,122 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "tapeserver/readtp/TapeFseqRangeSequence.hpp" +#include "tapeserver/readtp/TapeFseqRange.hpp" +#include "common/exception/Exception.hpp" + +#include <getopt.h> +#include <ostream> + +#include <list> + +namespace cta { +namespace tapeserver { +namespace readtp { + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +TapeFseqRangeSequence::TapeFseqRangeSequence() throw() { + reset(); +} + + +//------------------------------------------------------------------------------ +// constructor +//------------------------------------------------------------------------------ +TapeFseqRangeSequence::TapeFseqRangeSequence( + const TapeFseqRange &range) throw() { + reset(range); +} + + +//------------------------------------------------------------------------------ +// reset +//------------------------------------------------------------------------------ +void TapeFseqRangeSequence::reset() throw() { + + // Reset the range to be empty + m_range.reset(); + + m_next = 0; // Ignored +} + + +//------------------------------------------------------------------------------ +// reset +//------------------------------------------------------------------------------ +void TapeFseqRangeSequence::reset( + const TapeFseqRange &range) throw() { + m_range = range; + + if(range.isEmpty()) { + m_next = 0; // Ignored + } else { + m_next = m_range.lower(); + } +} + + +//------------------------------------------------------------------------------ +// hasMore +//------------------------------------------------------------------------------ +bool TapeFseqRangeSequence::hasMore() const throw() { + + if(m_range.isEmpty()) { + + return false; + + } else { + + // Infinity is represented by range.upper() == 0 + return m_range.upper() == 0 || m_next <= m_range.upper(); + } +} + + +//------------------------------------------------------------------------------ +// next +//------------------------------------------------------------------------------ +uint32_t TapeFseqRangeSequence::next() + { + + if(!hasMore()) { + exception::Exception ex; + + ex.getMessage() + << "Sequence::next() called after end of sequence"; + + throw ex; + } + + return m_next++; +} + + +//------------------------------------------------------------------------------ +// range +//------------------------------------------------------------------------------ +const TapeFseqRange + &TapeFseqRangeSequence::range() const throw() { + return m_range; +} + + +} // namespace readtp +} // namespace tapeserver +} // namespace cta \ No newline at end of file diff --git a/tapeserver/readtp/TapeFseqRangeSequence.hpp b/tapeserver/readtp/TapeFseqRangeSequence.hpp new file mode 100644 index 0000000000000000000000000000000000000000..ae068dfd0a68bc570711f93c733eb9b36331c7cd --- /dev/null +++ b/tapeserver/readtp/TapeFseqRangeSequence.hpp @@ -0,0 +1,100 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "TapeFseqRange.hpp" + +#include <list> + +namespace cta { +namespace tapeserver { +namespace readtp { + +/** + * Generates a sequence of tape file sequence numbers from a range of tape file + * sequence numbers. + */ +class TapeFseqRangeSequence { +public: + + /** + * Constructor. + * + * Constructs an empty sequence. + */ + TapeFseqRangeSequence() throw(); + + /** + * Constructor. + * + * @param range The range from which the sequence is generated. + */ + TapeFseqRangeSequence(const TapeFseqRange &range) throw(); + + /** + * Resets the sequence to empty. + */ + void reset() throw(); + + /** + * Resets the sequence using the specified range. + * + * @param range The range from which the sequence is generated. + */ + void reset(const TapeFseqRange &range) throw(); + + /** + * Returns true if there is another tape file sequence number in the + * sequence. + */ + bool hasMore() const throw(); + + /** + * Returns the next tape file sequence number in the sequence, or throws + * NoValue exception if there isn't one. + */ + uint32_t next() ; + + /** + * Returns the number of values generated by the sequence so far. + */ + uint32_t nbGeneratedValues() const throw(); + + /** + * Returns the range used by this sequence. + */ + const TapeFseqRange &range() const throw(); + + +private: + + /** + * The range from which the sequence is generated. + */ + TapeFseqRange m_range; + + /** + * The value to be returned by a call to next(). + */ + uint32_t m_next; + +}; // class TapeFseqRangeSequence + +} // namespace readtp +} // namespace tapeserver +} // namespace cta \ No newline at end of file diff --git a/tapeserver/readtp/TapeFseqSequenceParser.cpp b/tapeserver/readtp/TapeFseqSequenceParser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8e4d9a47c1547b30ed042a13bf1747056b453c1f --- /dev/null +++ b/tapeserver/readtp/TapeFseqSequenceParser.cpp @@ -0,0 +1,150 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "common/exception/InvalidArgument.hpp" +#include "tapeserver/readtp/TapeFseqSequenceParser.hpp" +#include "common/utils/utils.hpp" + +#include <list> +#include <string> +#include <vector> + +namespace cta { +namespace tapeserver { +namespace readtp { + +//------------------------------------------------------------------------------ +// parseTapeFileSequence +//------------------------------------------------------------------------------ +TapeFseqRangeList TapeFileSequenceParser::parse(char *const str) +{ + TapeFseqRangeList tapeFseqRanges; + std::vector<std::string> rangeStrs; + + // Range strings are separated by commas + utils::splitString(str, ',', rangeStrs); + + // For each range string + for(std::vector<std::string>::const_iterator itor=rangeStrs.begin(); + itor!=rangeStrs.end(); itor++) { + + std::vector<std::string> boundaryStrs; + + // Lower and upper boundary strings are separated by a dash ('-') + utils::splitString(*itor, '-', boundaryStrs); + + int nbBoundaries = boundaryStrs.size(); + + switch(nbBoundaries) { + case 1: // Range string = "n" + if(!utils::isValidUInt(boundaryStrs[0].c_str())) { + exception::InvalidArgument ex; + ex.getMessage() << "Invalid range string: '" << boundaryStrs[0] + << "': Expecting an unsigned integer"; + throw ex; + } + + { + const uint32_t upperLower = atoi(boundaryStrs[0].c_str()); + tapeFseqRanges.push_back(TapeFseqRange(upperLower, upperLower)); + } + break; + + case 2: // Range string = "m-n" or "-n" or "m-" or "-" + + // If "-n" or "-" then the range string is invalid + if(boundaryStrs[0] == "") { + exception::InvalidArgument ex; + ex.getMessage() << "Invalid range string: '" << *itor + << "': Strings of the form '-n' or '-' are invalid"; + throw ex; + } + + // At this point the range string must be either "m-n" or "m-" + + // Parse the "m" of "m-n" or "m-" + if(!utils::isValidUInt(boundaryStrs[0].c_str())) { + exception::InvalidArgument ex; + ex.getMessage() << "Invalid range string: '" << *itor + << "': The lower boundary should be an unsigned integer"; + throw ex; + } + + { + const uint32_t lower = atoi(boundaryStrs[0].c_str()); + + if(lower == 0) { + exception::InvalidArgument ex; + ex.getMessage() << "Invalid range string: '" << *itor + << "': The lower boundary can not be '0'"; + throw ex; + } + + // If "m-" + if(boundaryStrs[1] == "") { + + // Infinity (or until the end of tape) is represented by 0 + tapeFseqRanges.push_back(TapeFseqRange(lower, 0)); + + // Else "m-n" + } else { + + // Parse the "n" of "m-n" + if(!utils::isValidUInt(boundaryStrs[1].c_str())) { + exception::InvalidArgument ex; + ex.getMessage() << "Invalid range string: '" << *itor + << "': The upper boundary should be an unsigned integer"; + throw ex; + } + + const uint32_t upper = atoi(boundaryStrs[1].c_str()); + + if(upper == 0){ + exception::InvalidArgument ex; + ex.getMessage() << "Invalid range string: '" << *itor + << "': The upper boundary can not be '0'"; + throw ex; + } + + if(lower > upper){ + exception::InvalidArgument ex; + ex.getMessage() << "Invalid range string: '" << *itor + << "': The lower boundary cannot be greater than the upper " + "boundary"; + throw ex; + } + + tapeFseqRanges.push_back(TapeFseqRange(lower, upper)); + } // Else "m-n" + } + + + break; + + default: // Range string is invalid + exception::InvalidArgument ex; + ex.getMessage() << "Invalid range string: '" << *itor + << "': A range string can only contain one or no dashes ('-')"; + throw ex; + } + } + return tapeFseqRanges; +} + +} // namespace readtp +} // namespace tapeserver +} // namespace cta \ No newline at end of file diff --git a/tapeserver/readtp/TapeFseqSequenceParser.hpp b/tapeserver/readtp/TapeFseqSequenceParser.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d413ca27963e3fe1b0949e43eaf4d8a9695bbcde --- /dev/null +++ b/tapeserver/readtp/TapeFseqSequenceParser.hpp @@ -0,0 +1,58 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright(C) 2015-2021 CERN + * @license This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#pragma once + +#include "common/exception/Exception.hpp" +#include "tapeserver/readtp/TapeFseqRangeListSequence.hpp" + +#include <list> + +namespace cta { +namespace tapeserver { +namespace readtp { + +/** + * Helper class to parse tape file sequence parameter strings. + */ +class TapeFileSequenceParser { +public: + + /** + * Parse the specified tape file sequence parameter string and store the + * resulting ranges into m_parsedCommandLine.tapeFseqRanges. + * + * The syntax rules for a tape file sequence specification are: + * <ul> + * <li> f1 File f1. + * <li> f1-f2 Files f1 to f2 included. + * <li> f1- Files from f1 to the last file of the tape. + * <li> f1-f2,f4,f6- Series of ranges "," separated. + * </ul> + * + * @param str The string received as an argument for the TapeFileSequence + * option. + * @return The resulting list of tape file sequence ranges. + */ + static TapeFseqRangeList parse(char *const str) + ; + +}; // class TapeFileSequenceParser + +} // namespace readtp +} // namespace tapeserver +} // namespace cta \ No newline at end of file diff --git a/tapeserver/readtp/cta-readtp.1cta b/tapeserver/readtp/cta-readtp.1cta new file mode 100644 index 0000000000000000000000000000000000000000..cba3f3363f2719da2b2edd1c18f8f48690955eb0 --- /dev/null +++ b/tapeserver/readtp/cta-readtp.1cta @@ -0,0 +1,53 @@ +.\" @project The CERN Tape Archive (CTA) +.\" @copyright Copyright(C) 2019-2021 CERN +.\" @license This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. + +.TH CTA-READTP 1CTA "August 2021" CTA CTA +.SH NAME +cta-readtp \- Read files from a tape +.SH SYNOPSIS +.BI "cta-readtp VID SEQUENCE [OPTIONS]" + +.SH DESCRIPTION +\fBcta-readtp\fP is a command-line tool for reading files from tape and validating their checksums. + +The tape to be read is specified by the \fBVID\fP argument. The tape files to be read are specified as a \fBSEQUENCE\fP of tape file sequence numbers. The +syntax used to specify the sequence is as follows: + + f1-f2 Files f1 to f2 inclusive. + f1- Files f1 to the last file on the tape. + f1-f2,f4,f6- A series of non-consecutive ranges of files. + +.SH OPTIONS +.TP +.TP +\fB\-h, \-\-help +Prints the usage message. +.TP +\fB\-f, \-\-destination_files +Path to a file containing a list of URLs the read files will be written to. If not specified, read files will be written to file:///dev/null. +If there are more read files than destination files, the remaining read files will be written to file:///dev/null +.TP +\fB\-p, \-\-xroot_private_key +Path to the xroot private key file. Necessary if any destination file URL is for xroot. +. + +.SH RETURN VALUE +Zero on success and non-zero on failure. +.SH EXAMPLES +.br +cta-readtp V01007 10002,10004-10006,10008- + +.SH AUTHOR +\fBCTA\fP Team diff --git a/xroot_plugins/XrdCtaTapeFileLs.hpp b/xroot_plugins/XrdCtaTapeFileLs.hpp index a90582ebfa3419cea7e735ed6071fdce597063ca..ca813935ca409d01424f53514348b619e70aba8a 100644 --- a/xroot_plugins/XrdCtaTapeFileLs.hpp +++ b/xroot_plugins/XrdCtaTapeFileLs.hpp @@ -94,8 +94,7 @@ TapeFileLsStream::TapeFileLsStream(const RequestMessage &requestMsg, } searchCriteria.diskFileIds->push_back(std::to_string(fid)); } - // Disk instance on its own does not give a valid set of search criteria (no &has_any) - searchCriteria.diskInstance = requestMsg.getOptional(OptionString::INSTANCE); + searchCriteria.diskInstance = requestMsg.getOptional(OptionString::INSTANCE, &has_any); searchCriteria.archiveFileId = requestMsg.getOptional(OptionUInt64::ARCHIVE_FILE_ID, &has_any); diff --git a/xroot_plugins/XrdCtaVirtualOrganizationLs.hpp b/xroot_plugins/XrdCtaVirtualOrganizationLs.hpp index 8bf8e52bb97af9fba5d58e813a8fa71e5188b8ff..df59a73646c487bbd2ba3d74a3c8214af6737939 100644 --- a/xroot_plugins/XrdCtaVirtualOrganizationLs.hpp +++ b/xroot_plugins/XrdCtaVirtualOrganizationLs.hpp @@ -77,6 +77,7 @@ int VirtualOrganizationLsStream::fillBuffer(XrdSsiPb::OStreamBuffer<Data> *strea vo_item->set_name(vo.name); vo_item->set_read_max_drives(vo.readMaxDrives); vo_item->set_write_max_drives(vo.writeMaxDrives); + vo_item->set_max_file_size(vo.maxFileSize); vo_item->mutable_creation_log()->set_username(vo.creationLog.username); vo_item->mutable_creation_log()->set_host(vo.creationLog.host); vo_item->mutable_creation_log()->set_time(vo.creationLog.time); diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.cpp b/xroot_plugins/XrdSsiCtaRequestMessage.cpp index 5ed7a836baa8e54fe8907454f6823cd9a710e95b..41c60c3f4af9ccae61df808f77c920fe384ff51f 100644 --- a/xroot_plugins/XrdSsiCtaRequestMessage.cpp +++ b/xroot_plugins/XrdSsiCtaRequestMessage.cpp @@ -282,6 +282,10 @@ void RequestMessage::process(const cta::xrd::Request &request, cta::xrd::Respons case cmd_pair(AdminCmd::CMD_RECYCLETAPEFILE, AdminCmd::SUBCMD_LS): processRecycleTapeFile_Ls(response,stream); break; + case cmd_pair(AdminCmd::CMD_RECYCLETAPEFILE, AdminCmd::SUBCMD_RESTORE): + processRecycleTapeFile_Restore(response); + break; + default: throw PbException("Admin command pair <" + AdminCmd_Cmd_Name(request.admincmd().cmd()) + ", " + @@ -467,10 +471,12 @@ void RequestMessage::processCLOSEW(const cta::eos::Notification ¬ification, c throw PbException("File is in fail_on_closew_test storage class, which always fails."); } + auto storageClass = m_catalogue.getStorageClass(storageClassItor->second); + // Disallow archival of files above the specified limit - if(notification.file().size() > m_archiveFileMaxSize) { + if(storageClass.vo.maxFileSize && notification.file().size() > storageClass.vo.maxFileSize) { throw exception::UserError("Archive request rejected: file size (" + std::to_string(notification.file().size()) + - " bytes) exceeds maximum allowed size (" + std::to_string(m_archiveFileMaxSize) + " bytes)"); + " bytes) exceeds maximum allowed size (" + std::to_string(storageClass.vo.maxFileSize) + " bytes)"); } cta::common::dataStructures::ArchiveRequest request; @@ -1833,7 +1839,7 @@ void RequestMessage::processTapeFile_Rm(cta::xrd::Response &response) } else if (diskFileId) { if (!instance) { throw exception::UserError(std::string("--fxid requires that --instance is specified")); - } + } m_catalogue.deleteTapeFileCopy(vid, diskFileId.value(), instance.value(), reason); response.set_type(cta::xrd::Response::RSP_SUCCESS); } else { @@ -1999,6 +2005,7 @@ void RequestMessage::processVirtualOrganization_Add(cta::xrd::Response &response const auto &readMaxDrives = getRequired(OptionUInt64::READ_MAX_DRIVES); const auto &writeMaxDrives = getRequired(OptionUInt64::WRITE_MAX_DRIVES); const auto &comment = getRequired(OptionString::COMMENT); + const auto &maxFileSizeOpt = getOptional(OptionUInt64::MAX_FILE_SIZE); cta::common::dataStructures::VirtualOrganization vo; vo.name = name; @@ -2006,6 +2013,12 @@ void RequestMessage::processVirtualOrganization_Add(cta::xrd::Response &response vo.writeMaxDrives = writeMaxDrives; vo.comment = comment; + if (maxFileSizeOpt) { + vo.maxFileSize = maxFileSizeOpt.value(); + } else { + vo.maxFileSize = m_archiveFileMaxSize; + } + m_catalogue.createVirtualOrganization(m_cliIdentity,vo); response.set_type(cta::xrd::Response::RSP_SUCCESS); @@ -2018,6 +2031,7 @@ void RequestMessage::processVirtualOrganization_Ch(cta::xrd::Response &response) const auto readMaxDrives = getOptional(OptionUInt64::READ_MAX_DRIVES); const auto writeMaxDrives = getOptional(OptionUInt64::WRITE_MAX_DRIVES); const auto comment = getOptional(OptionString::COMMENT); + const auto maxFileSize = getOptional(OptionUInt64::MAX_FILE_SIZE); if(comment) m_catalogue.modifyVirtualOrganizationComment(m_cliIdentity,name,comment.value()); @@ -2028,6 +2042,9 @@ void RequestMessage::processVirtualOrganization_Ch(cta::xrd::Response &response) if(writeMaxDrives) m_catalogue.modifyVirtualOrganizationWriteMaxDrives(m_cliIdentity,name,writeMaxDrives.value()); + if(maxFileSize) + m_catalogue.modifyVirtualOrganizationMaxFileSize(m_cliIdentity,name,maxFileSize.value()); + response.set_type(cta::xrd::Response::RSP_SUCCESS); } @@ -2147,4 +2164,39 @@ void RequestMessage::processRecycleTapeFile_Ls(cta::xrd::Response &response, Xrd response.set_type(cta::xrd::Response::RSP_SUCCESS); } +void RequestMessage::processRecycleTapeFile_Restore(cta::xrd::Response& response) { + response.set_type(cta::xrd::Response::RSP_SUCCESS); + using namespace cta::admin; + + bool has_any = false; + cta::catalogue::RecycleTapeFileSearchCriteria searchCriteria; + + searchCriteria.vid = getOptional(OptionString::VID, &has_any); + auto diskFileId = getOptional(OptionString::FXID, &has_any); + searchCriteria.diskFileIds = getOptional(OptionStrList::FILE_ID, &has_any); + + if(diskFileId){ + // single option on the command line we need to do the conversion ourselves. + if(!searchCriteria.diskFileIds) searchCriteria.diskFileIds = std::vector<std::string>(); + + auto fid = strtol(diskFileId->c_str(), nullptr, 16); + if(fid < 1 || fid == LONG_MAX) { + throw cta::exception::UserError(*diskFileId + " is not a valid file ID"); + } + + searchCriteria.diskFileIds->push_back(std::to_string(fid)); + } + // Disk instance on its own does not give a valid set of search criteria (no &has_any) + searchCriteria.diskInstance = getOptional(OptionString::INSTANCE); + searchCriteria.archiveFileId = getOptional(OptionUInt64::ARCHIVE_FILE_ID, &has_any); + // Copy number on its own does not give a valid set of search criteria (no &has_any) + searchCriteria.copynb = getOptional(OptionUInt64::COPY_NUMBER); + + if(!has_any){ + throw cta::exception::UserError("Must specify at least one search option"); + } + m_catalogue.restoreFilesInRecycleLog(searchCriteria); + response.set_type(cta::xrd::Response::RSP_SUCCESS); +} + }} // namespace cta::xrd diff --git a/xroot_plugins/XrdSsiCtaRequestMessage.hpp b/xroot_plugins/XrdSsiCtaRequestMessage.hpp index fb9b2f4f27b2eda48cb1a1db3992f2010c1c35e3..616516bcffb2c4851334ba0f580e9f2f2388eaca 100644 --- a/xroot_plugins/XrdSsiCtaRequestMessage.hpp +++ b/xroot_plugins/XrdSsiCtaRequestMessage.hpp @@ -208,6 +208,7 @@ private: void processVirtualOrganization_Add(cta::xrd::Response &response); void processVirtualOrganization_Ch(cta::xrd::Response &response); void processVirtualOrganization_Rm(cta::xrd::Response &response); + void processRecycleTapeFile_Restore(cta::xrd::Response &response); /*! * Process AdminCmd events which can return a stream response diff --git a/xroot_plugins/XrdSsiCtaServiceProvider.cpp b/xroot_plugins/XrdSsiCtaServiceProvider.cpp index df4cc19b2cffb7033735d7b3c9a3f6ddab3c2d02..ededf3116c4f71909a09d4d909c55d66e195cf65 100644 --- a/xroot_plugins/XrdSsiCtaServiceProvider.cpp +++ b/xroot_plugins/XrdSsiCtaServiceProvider.cpp @@ -153,7 +153,7 @@ void XrdSsiCtaServiceProvider::ExceptionThrowingInit(XrdSsiLogger *logP, XrdSsiC // Initialise the Frontend auto archiveFileMaxSize = config.getOptionValueInt("cta.archivefile.max_size_gb"); - m_archiveFileMaxSize = archiveFileMaxSize.first ? archiveFileMaxSize.second : 2048; // GB + m_archiveFileMaxSize = archiveFileMaxSize.first ? archiveFileMaxSize.second : 0; // GB m_archiveFileMaxSize *= 1024*1024*1024; // bytes // Get the repack buffer URL diff --git a/xrootd-ssi-protobuf-interface b/xrootd-ssi-protobuf-interface index 2f8068955f6622f26e6373a70cfcb4f16435d7ea..533402d24924f0450924d4f07d0b8450398ab203 160000 --- a/xrootd-ssi-protobuf-interface +++ b/xrootd-ssi-protobuf-interface @@ -1 +1 @@ -Subproject commit 2f8068955f6622f26e6373a70cfcb4f16435d7ea +Subproject commit 533402d24924f0450924d4f07d0b8450398ab203