From b17119004c5d1d00c60436deb831d85ac7d9eaed Mon Sep 17 00:00:00 2001 From: KarlLevik Date: Fri, 27 Jun 2025 17:15:42 +0100 Subject: [PATCH 1/2] Use 'if not exists' when creating role --- grants/ispyb_expeye.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grants/ispyb_expeye.sql b/grants/ispyb_expeye.sql index 0bebdb3..359d91f 100644 --- a/grants/ispyb_expeye.sql +++ b/grants/ispyb_expeye.sql @@ -8,7 +8,7 @@ CREATE ROLE IF NOT EXISTS ispyb_expeye_core_role; GRANT ispyb_propagation TO ispyb_expeye_core_role; -CREATE ROLE ispyb_expeye_acquisition_role; +CREATE ROLE IF NOT EXISTS ispyb_expeye_acquisition_role; GRANT SELECT, INSERT, UPDATE, DELETE ON Proposal TO ispyb_expeye_acquisition_role; GRANT SELECT, INSERT, UPDATE, DELETE ON BLSession TO ispyb_expeye_acquisition_role; From fee2848e31a92f63887691a98170466f60acf228 Mon Sep 17 00:00:00 2001 From: KarlLevik Date: Fri, 27 Jun 2025 17:16:14 +0100 Subject: [PATCH 2/2] Refresh schema files --- schemas/ispyb/lookups.sql | 11 +++- schemas/ispyb/routines.sql | 118 +++++++++++++++++++++++++++++++++++-- schemas/ispyb/tables.sql | 49 ++++++++++++++- 3 files changed, 169 insertions(+), 9 deletions(-) diff --git a/schemas/ispyb/lookups.sql b/schemas/ispyb/lookups.sql index ab7080f..48671a5 100644 --- a/schemas/ispyb/lookups.sql +++ b/schemas/ispyb/lookups.sql @@ -287,7 +287,13 @@ INSERT INTO `SchemaStatus` (`schemaStatusId`, `scriptName`, `schemaStatus`, `rec (315,'2025_05_01_BLSamplePosition.sql','DONE','2025-05-09 15:21:06'), (316,'2025_05_01_XrayCentringResult_fk_blSampleId.sql','DONE','2025-05-09 15:21:06'), (317,'2025_05_02_BLSamplePosition_rename_column.sql','DONE','2025-05-09 15:21:06'), -(318,'2025_05_12_AdminVar_bump_version.sql','DONE','2025-05-09 15:21:06'); +(318,'2025_05_12_AdminVar_bump_version.sql','DONE','2025-05-09 15:21:06'), +(319,'2025_05_14_BLSamplePosition_recordTimeStamp_default.sql','DONE','2025-06-27 16:04:05'), +(320,'2025_05_23_Ligand_and_junction_tables.sql','DONE','2025-06-27 16:04:05'), +(321,'2025_05_28_BLSession_icatId.sql','DONE','2025-06-27 16:04:05'), +(322,'2025_06_02_DewarRegistry_type.sql','DONE','2025-06-27 16:04:05'), +(323,'2025_06_26_ContainerType_cryoem_puck.sql','DONE','2025-06-27 16:04:05'), +(324,'2025_06_27_Tomogram_pixelLocation.sql','DONE','2025-06-27 16:04:05'); /*!40000 ALTER TABLE `SchemaStatus` ENABLE KEYS */; /*!40000 ALTER TABLE `ComponentType` DISABLE KEYS */; @@ -358,7 +364,8 @@ INSERT INTO `ContainerType` (`containerTypeId`, `name`, `proposalType`, `active` (34,'I22_Grid_81','saxs',1,81,9,1,1,1,1,0,0,-1), (35,'I22_Capillary_Rack_25','saxs',1,25,25,1,1,1,1,0,0,-1), (36,'VMXm-Cartridge','mx',1,5,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), -(37,'VMXm-GridBox','mx',1,4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); +(37,'VMXm-GridBox','mx',1,4,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL), +(38,'Cryo-EM Puck','mx',1,12,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `ContainerType` ENABLE KEYS */; /*!40000 ALTER TABLE `ExperimentType` DISABLE KEYS */; diff --git a/schemas/ispyb/routines.sql b/schemas/ispyb/routines.sql index 335dede..00420fa 100644 --- a/schemas/ispyb/routines.sql +++ b/schemas/ispyb/routines.sql @@ -4190,25 +4190,27 @@ BEGIN SELECT d.dewarId "id", d.shippingId "shippingId", d.code "name", d.comments "comments", d.storageLocation "storageLocation", d.dewarStatus "status", d.isStorageDewar "isStorageDewar", d.barCode "barCode", d.firstExperimentId "firstSessionId", - d.type "type", d.facilityCode "facilityCode", d.weight "weight", d.deliveryAgent_barcode "deliveryAgentBarcode" + dr.type "type", d.facilityCode "facilityCode", d.weight "weight", d.deliveryAgent_barcode "deliveryAgentBarcode" FROM Dewar d + LEFT JOIN DewarRegistry dr ON dr.facilityCode = d.facilityCode INNER JOIN Shipping s ON s.shippingId = d.shippingId - INNER JOIN Proposal p ON p.proposalId = s.proposalId + INNER JOIN Proposal p ON p.proposalId = s.proposalId INNER JOIN BLSession bs ON bs.proposalId = s.proposalId INNER JOIN Session_has_Person shp ON bs.sessionId = shp.sessionId INNER JOIN Person per ON per.personId = shp.personId WHERE per.login = p_authLogin AND p.proposalCode = p_proposalCode AND p.proposalNumber = p_proposalNumber GROUP BY d.dewarId, d.shippingId, d.code, d.comments, d.storageLocation, d.dewarStatus, d.isStorageDewar, d.barCode, d.firstExperimentId, - d.type, d.facilityCode, d.weight, d.deliveryAgent_barcode; + dr.type, d.facilityCode, d.weight, d.deliveryAgent_barcode; ELSE SELECT d.dewarId "id", d.shippingId "shippingId", d.code "name", d.comments "comments", d.storageLocation "storageLocation", d.dewarStatus "status", d.isStorageDewar "isStorageDewar", d.barCode "barCode", d.firstExperimentId "firstSessionId", - d.type "type", d.facilityCode "facilityCode", d.weight "weight", d.deliveryAgent_barcode "deliveryAgentBarcode" + dr.type "type", d.facilityCode "facilityCode", d.weight "weight", d.deliveryAgent_barcode "deliveryAgentBarcode" FROM Dewar d + LEFT JOIN DewarRegistry dr ON dr.facilityCode = d.facilityCode INNER JOIN Shipping s ON s.shippingId = d.shippingId - INNER JOIN Proposal p ON p.proposalId = s.proposalId + INNER JOIN Proposal p ON p.proposalId = s.proposalId WHERE p.proposalCode = p_proposalCode AND p.proposalNumber = p_proposalNumber; END IF; @@ -9996,6 +9998,112 @@ DELIMITER ; /*!50003 SET character_set_results = @saved_cs_results */ ; /*!50003 SET collation_connection = @saved_col_connection */ ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; +/*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; +/*!50003 DROP PROCEDURE IF EXISTS `upsert_dewar_v3` */; +/*!50003 SET @saved_cs_client = @@character_set_client */ ; +/*!50003 SET @saved_cs_results = @@character_set_results */ ; +/*!50003 SET @saved_col_connection = @@collation_connection */ ; +/*!50003 SET character_set_client = utf8mb3 */ ; +/*!50003 SET character_set_results = utf8mb3 */ ; +/*!50003 SET collation_connection = utf8mb3_general_ci */ ; +DELIMITER ;; +CREATE PROCEDURE `upsert_dewar_v3`( + + INOUT p_id int(10) unsigned, + p_authLogin varchar(45), + p_shippingId int(10) unsigned, + p_name varchar(45), + p_comments tinytext, + p_storageLocation varchar(45), + p_status varchar(45), + p_isStorageDewar tinyint(1), + p_barcode varchar(45), + p_firstSessionId int(10) unsigned, + p_customsValue int(11) unsigned, + p_transportValue int(11) unsigned, + p_trackingNumberToSynchrotron varchar(30), + p_trackingNumberFromSynchrotron varchar(30), + p_facilityCode varchar(20), + p_weight float, + p_deliveryAgentBarcode varchar(30) + ) + MODIFIES SQL DATA + COMMENT 'Inserts or updates info about a dewar/parcel (p_id).\nMandatory columns:\nFor insert: none\nFor update: p_id \nReturns: Record ID in p_id.' +BEGIN + DECLARE row_storageLocation varchar(45) DEFAULT NULL; + DECLARE row_dewarStatus varchar(45) DEFAULT NULL; + DECLARE row_count int unsigned DEFAULT 0; + + IF p_storageLocation IS NULL THEN + SIGNAL SQLSTATE '45000' SET MYSQL_ERRNO=1644, MESSAGE_TEXT='Mandatory argument p_storageLocation is NULL'; + END IF; + + IF p_authLogin IS NOT NULL AND p_shippingId IS NOT NULL THEN + + + + SELECT count(*) INTO row_count + FROM Shipping s + INNER JOIN BLSession bs ON bs.proposalId = s.proposalId + INNER JOIN Session_has_Person shp ON bs.sessionId = shp.sessionId + INNER JOIN Person p ON p.personId = shp.personId + WHERE p.login = p_authLogin AND s.shippingId = p_shippingId; + + IF row_count = 0 THEN + SIGNAL SQLSTATE '02000' + SET MYSQL_ERRNO=1643, MESSAGE_TEXT = 'Dewar not in a shipping belonging to one of the p_authLogin Person sessions'; + END IF; + END IF; + + IF p_id IS NULL THEN + INSERT INTO Dewar(dewarId,shippingId,code,comments,storageLocation,dewarStatus,isStorageDewar,barCode,firstExperimentId,customsValue,transportValue, + trackingNumberToSynchrotron,trackingNumberFromSynchrotron,FACILITYCODE,weight,deliveryAgent_barcode) + VALUES (p_id, p_shippingId, p_name, p_comments, p_storageLocation, p_status, p_isStorageDewar, p_barcode, p_firstSessionId, p_customsValue, p_transportValue, + p_trackingNumberToSynchrotron, p_trackingNumberFromSynchrotron, p_facilityCode, p_weight, p_deliveryAgentBarcode); + SET p_id = LAST_INSERT_ID(); + ELSE + + SELECT storageLocation, dewarStatus INTO row_storageLocation, row_dewarStatus FROM Dewar WHERE dewarId = p_id; + + UPDATE Dewar + SET shippingId = IFNULL(p_shippingId, shippingId), + code = IFNULL(p_name, code), + comments = IFNULL(p_comments, comments), + storageLocation = IFNULL(p_storageLocation, storageLocation), + dewarStatus = IFNULL(p_status, dewarStatus), + isStorageDewar = IFNULL(p_isStorageDewar, isStorageDewar), + barCode = IFNULL(p_barcode, barCode), + firstExperimentId = IFNULL(p_firstSessionId, firstExperimentId), + customsValue = IFNULL(p_customsValue, customsValue), + transportValue = IFNULL(p_transportValue, transportValue), + trackingNumberToSynchrotron = IFNULL(p_trackingNumberToSynchrotron, trackingNumberToSynchrotron), + trackingNumberFromSynchrotron = IFNULL(p_trackingNumberFromSynchrotron, trackingNumberFromSynchrotron), + FACILITYCODE = IFNULL(p_facilityCode, FACILITYCODE), + weight = IFNULL(p_weight, weight), + deliveryAgent_barcode = IFNULL(p_deliveryAgentBarcode, deliveryAgent_barcode) + WHERE dewarId = p_id; + + + IF row_storageLocation <> p_storageLocation OR row_dewarStatus <> p_status THEN + INSERT INTO DewarTransportHistory (dewarId, dewarStatus, storageLocation, arrivalDate) + VALUES (p_id, p_status, p_storageLocation, NOW()); + END IF; + + + IF row_storageLocation <> p_storageLocation THEN + + UPDATE Container + SET sampleChangerLocation = '', containerStatus = 'at facility' + WHERE dewarId = p_id; + END IF; + END IF; +END ;; +DELIMITER ; +/*!50003 SET sql_mode = @saved_sql_mode */ ; +/*!50003 SET character_set_client = @saved_cs_client */ ; +/*!50003 SET character_set_results = @saved_cs_results */ ; +/*!50003 SET collation_connection = @saved_col_connection */ ; +/*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; /*!50003 DROP PROCEDURE IF EXISTS `upsert_energy_scan` */; /*!50003 SET @saved_cs_client = @@character_set_client */ ; diff --git a/schemas/ispyb/tables.sql b/schemas/ispyb/tables.sql index 0b8b6ff..ac9021a 100644 --- a/schemas/ispyb/tables.sql +++ b/schemas/ispyb/tables.sql @@ -614,12 +614,12 @@ CREATE TABLE `BLSamplePosition` ( `posX` double DEFAULT NULL, `posY` double DEFAULT NULL, `posZ` double DEFAULT NULL, - `recordTimeStamp` datetime DEFAULT NULL COMMENT 'Creation or last update date/time', + `recordTimeStamp` datetime DEFAULT current_timestamp(), `positionType` enum('dispensing') DEFAULT NULL COMMENT 'Type of marked position (e.g.: dispensing location)', PRIMARY KEY (`blSamplePositionId`), KEY `BLSamplePosition_fk_blSampleId` (`blSampleId`), CONSTRAINT `BLSamplePosition_fk_blSampleId` FOREIGN KEY (`blSampleId`) REFERENCES `BLSample` (`blSampleId`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; /*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `BLSampleType`; /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -672,6 +672,18 @@ CREATE TABLE `BLSample_has_EnergyScan` ( CONSTRAINT `BLSample_has_EnergyScan_ibfk_2` FOREIGN KEY (`energyScanId`) REFERENCES `EnergyScan` (`energyScanId`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `BLSample_has_Ligand`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `BLSample_has_Ligand` ( + `blSampleId` int(10) unsigned NOT NULL, + `ligandId` int(11) unsigned NOT NULL, + PRIMARY KEY (`blSampleId`,`ligandId`), + KEY `BLSample_has_Ligand_fk2` (`ligandId`), + CONSTRAINT `BLSample_has_Ligand_fk1` FOREIGN KEY (`blSampleId`) REFERENCES `BLSample` (`blSampleId`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `BLSample_has_Ligand_fk2` FOREIGN KEY (`ligandId`) REFERENCES `Ligand` (`ligandId`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Junction table for BLSample and Ligand'; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `BLSample_has_Positioner`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; @@ -709,6 +721,7 @@ CREATE TABLE `BLSession` ( `archived` tinyint(1) DEFAULT 0 COMMENT 'The data for the session is archived and no longer available on disk', `riskRating` enum('Low','Medium','High','Not Permitted') DEFAULT NULL COMMENT 'ERA in user admin system', `purgedProcessedData` tinyint(1) DEFAULT 0 COMMENT 'Flag to indicate whether the processed folder in the associated visit directory has been purged', + `icatId` int(11) unsigned DEFAULT NULL COMMENT 'The internal ICAT ID for this BLSession', PRIMARY KEY (`sessionId`), UNIQUE KEY `proposalId` (`proposalId`,`visit_number`), KEY `Session_FKIndex2` (`beamLineSetupId`), @@ -1677,6 +1690,7 @@ CREATE TABLE `DewarRegistry` ( `purchaseDate` datetime DEFAULT NULL, `bltimestamp` datetime NOT NULL DEFAULT current_timestamp(), `manufacturerSerialNumber` varchar(15) DEFAULT NULL COMMENT 'Dewar serial number as given by manufacturer. Used to be typically 5 or 6 digits, more likely to be 11 alphanumeric chars in future', + `type` enum('Dewar','Toolbox','Thermal Shipper') NOT NULL DEFAULT 'Dewar', PRIMARY KEY (`dewarRegistryId`), UNIQUE KEY `facilityCode` (`facilityCode`), KEY `DewarRegistry_ibfk_1` (`proposalId`), @@ -2195,6 +2209,35 @@ CREATE TABLE `Laboratory` ( PRIMARY KEY (`laboratoryId`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `Ligand`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `Ligand` ( + `ligandId` int(11) unsigned NOT NULL AUTO_INCREMENT, + `proposalId` int(10) unsigned NOT NULL COMMENT 'References Proposal table', + `name` varchar(30) NOT NULL COMMENT 'Ligand name', + `SMILES` varchar(400) DEFAULT NULL COMMENT 'Chemical structure', + `libraryName` varchar(30) DEFAULT NULL COMMENT 'Name of ligand library, to preserve provenance', + `libraryBatchNumber` varchar(30) DEFAULT NULL COMMENT 'Batch number of library, to preserve provenance', + `plateBarcode` varchar(30) DEFAULT NULL COMMENT 'Specific barcode of the plate it came from, to preserve provenance', + `sourceWell` varchar(30) DEFAULT NULL COMMENT 'Location within that plate, to preserve provenance', + PRIMARY KEY (`ligandId`), + KEY `Ligand_fk_proposalId` (`proposalId`), + CONSTRAINT `Ligand_fk_proposalId` FOREIGN KEY (`proposalId`) REFERENCES `Proposal` (`proposalId`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Ligands in biochemistry are substances that bind to biomolecules'; +/*!40101 SET character_set_client = @saved_cs_client */; +DROP TABLE IF EXISTS `Ligand_has_PDB`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `Ligand_has_PDB` ( + `ligandId` int(11) unsigned NOT NULL, + `pdbId` int(11) unsigned NOT NULL, + PRIMARY KEY (`ligandId`,`pdbId`), + KEY `Ligand_Has_PDB_fk2` (`pdbId`), + CONSTRAINT `Ligand_Has_PDB_fk1` FOREIGN KEY (`ligandId`) REFERENCES `Ligand` (`ligandId`) ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT `Ligand_Has_PDB_fk2` FOREIGN KEY (`pdbId`) REFERENCES `PDB` (`pdbId`) ON DELETE CASCADE ON UPDATE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Junction table for Ligand and PDB'; +/*!40101 SET character_set_client = @saved_cs_client */; DROP TABLE IF EXISTS `MXMRRun`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; @@ -2414,6 +2457,8 @@ CREATE TABLE `ParticleClassification` ( `bFactorFitQuadratic` float DEFAULT NULL COMMENT 'Quadratic coefficient of quadratic fit to refinement resolution against the logarithm of the number of particles', `angularEfficiency` double DEFAULT NULL COMMENT 'Variation in resolution across different angles, 1-2sig/mean', `suggestedTilt` double DEFAULT NULL COMMENT 'Suggested stage tilt angle to improve angular efficiency. Unit: degrees', + `pixelLocationX` int(11) DEFAULT NULL COMMENT 'pixel location of tomogram centre on search map image (x)', + `pixelLocationY` int(11) DEFAULT NULL COMMENT 'pixel location of tomogram centre on search map image (y)', PRIMARY KEY (`particleClassificationId`), KEY `ParticleClassification_fk_particleClassificationGroupId` (`particleClassificationGroupId`), CONSTRAINT `ParticleClassification_fk_particleClassificationGroupId` FOREIGN KEY (`particleClassificationGroupId`) REFERENCES `ParticleClassificationGroup` (`particleClassificationGroupId`) ON DELETE CASCADE ON UPDATE CASCADE