diff --git a/api/src/org/labkey/api/Constants.java b/api/src/org/labkey/api/Constants.java
index 50ce1f2e13e..9f4f6108f46 100644
--- a/api/src/org/labkey/api/Constants.java
+++ b/api/src/org/labkey/api/Constants.java
@@ -47,7 +47,7 @@ public static double getLowestSchemaVersion()
*/
public static double getEarliestUpgradeVersion()
{
- return 24.000;
+ return 25.000;
}
/**
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-0.000-24.000.sql b/assay/resources/schemas/dbscripts/postgresql/assay-0.000-24.000.sql
deleted file mode 100644
index 67a7f22a10a..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-0.000-24.000.sql
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- For LabKey 19.2 and earlier, the assayresult schema and the Plate, WellGroup, and Well tables were managed by the
- study module. As of 19.3, the assay module now manages these objects, with the tables moving from the "study" schema
- to the new "assay" schema.
- */
-
-CREATE SCHEMA assay;
-CREATE SCHEMA assayresult;
-
-CREATE TABLE assay.Plate
-(
- RowId SERIAL,
- LSID VARCHAR(200) NOT NULL,
- Container ENTITYID NOT NULL,
- Name VARCHAR(200) NULL,
- CreatedBy USERID NOT NULL,
- Created TIMESTAMP NOT NULL,
- Template BOOLEAN NOT NULL,
- DataFileId ENTITYID,
- Rows INT NOT NULL,
- Columns INT NOT NULL,
- Type VARCHAR(200),
-
- CONSTRAINT PK_Plate PRIMARY KEY (RowId)
-);
-
-CREATE INDEX IX_Plate_Container ON assay.Plate(Container);
-
-ALTER TABLE assay.plate
- ADD Modified TIMESTAMP,
- ADD ModifiedBy USERID;
-
-ALTER TABLE assay.plate
- ALTER Modified SET NOT NULL,
- ALTER ModifiedBy SET NOT NULL;
-
-ALTER TABLE assay.plate
- ADD CONSTRAINT uq_plate_lsid UNIQUE (lsid);
-
--- plate template (not instances) names are unique in each container
-CREATE UNIQUE INDEX uq_plate_container_name_template ON assay.plate (container, name) WHERE template=true;
-
-CREATE TABLE assay.WellGroup
-(
- RowId SERIAL,
- PlateId INT NOT NULL,
- LSID VARCHAR(200) NOT NULL,
- Container ENTITYID NOT NULL,
- Name VARCHAR(200) NULL,
- Template BOOLEAN NOT NULL,
- TypeName VARCHAR(50) NOT NULL,
-
- CONSTRAINT PK_WellGroup PRIMARY KEY (RowId),
- CONSTRAINT FK_WellGroup_Plate FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId)
-);
-
-CREATE INDEX IX_WellGroup_PlateId ON assay.WellGroup(PlateId);
-CREATE INDEX IX_WellGroup_Container ON assay.WellGroup(Container);
-
-ALTER TABLE assay.wellgroup
- ADD CONSTRAINT uq_wellgroup_lsid UNIQUE (lsid);
-
--- well group names must be unique within each well group type
-ALTER TABLE assay.wellgroup
- ADD CONSTRAINT uq_wellgroup_plateid_typename_name UNIQUE (plateid, typename, name);
-
-CREATE TABLE assay.Well
-(
- RowId SERIAL,
- LSID VARCHAR(200) NOT NULL,
- Container ENTITYID NOT NULL,
- Value FLOAT NULL,
- Dilution FLOAT NULL,
- PlateId INT NOT NULL,
- Row INT NOT NULL,
- Col INT NOT NULL,
-
- CONSTRAINT PK_Well PRIMARY KEY (RowId),
- CONSTRAINT FK_Well_Plate FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId)
-);
-
-CREATE INDEX IX_Well_PlateId ON assay.Well(PlateId);
-CREATE INDEX IX_Well_Container ON assay.Well(Container);
-
-ALTER TABLE assay.well
- ADD CONSTRAINT uq_well_lsid UNIQUE (lsid);
-
--- each well position is unique on the plate
-ALTER TABLE assay.well
- ADD CONSTRAINT uq_well_plateid_row_col UNIQUE (plateid, row, col);
-
-ALTER TABLE Assay.Well ADD COLUMN SampleId INTEGER NULL;
-ALTER TABLE Assay.Well ADD CONSTRAINT FK_SampleId_ExpMaterial FOREIGN KEY (SampleId) REFERENCES exp.material (RowId);
-
-CREATE TABLE assay.WellGroupPositions
-(
- RowId SERIAL,
- WellId INT NOT NULL,
- WellGroupId INT NOT NULL,
-
- CONSTRAINT PK_WellGroupPositions PRIMARY KEY (RowId),
- CONSTRAINT FK_WellGroupPositions_Well FOREIGN KEY (WellId) REFERENCES assay.Well(RowId),
- CONSTRAINT FK_WellGroupPositions_WellGroup FOREIGN KEY (WellGroupId) REFERENCES assay.WellGroup(RowId),
- CONSTRAINT UQ_WellGroupPositions_WellGroup_Well UNIQUE (WellGroupId, WellId)
-);
-
-CREATE TABLE assay.PlateProperty
-(
- RowId SERIAL,
- PlateId INT NOT NULL,
- PropertyId INT NOT NULL,
- PropertyURI VARCHAR(300) NOT NULL,
-
- CONSTRAINT PK_PlateProperty PRIMARY KEY (RowId),
- CONSTRAINT UQ_PlateProperty_PlateId_PropertyId UNIQUE (PlateId, PropertyId),
- CONSTRAINT FK_PlateProperty_PlateId FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId),
- CONSTRAINT FK_PlateProperty_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor(PropertyId)
-);
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-0.000-25.000.sql b/assay/resources/schemas/dbscripts/postgresql/assay-0.000-25.000.sql
new file mode 100644
index 00000000000..97baa9392f2
--- /dev/null
+++ b/assay/resources/schemas/dbscripts/postgresql/assay-0.000-25.000.sql
@@ -0,0 +1,332 @@
+/*
+ For LabKey 19.2 and earlier, the assayresult schema and the Plate, WellGroup, and Well tables were managed by the
+ study module. As of 19.3, the assay module now manages these objects, with the tables moving from the "study" schema
+ to the new "assay" schema.
+ */
+
+CREATE SCHEMA assay;
+CREATE SCHEMA assayresult;
+-- Provisioned schema used by PlateMetadataDomainKind
+CREATE SCHEMA assaywell;
+
+CREATE TABLE assay.Plate
+(
+ RowId SERIAL,
+ LSID VARCHAR(200) NOT NULL,
+ Container ENTITYID NOT NULL,
+ Name VARCHAR(200) NULL,
+ CreatedBy USERID NOT NULL,
+ Created TIMESTAMP NOT NULL,
+ Template BOOLEAN NOT NULL,
+ DataFileId ENTITYID,
+ Rows INT NOT NULL,
+ Columns INT NOT NULL,
+ Type VARCHAR(200),
+
+ CONSTRAINT PK_Plate PRIMARY KEY (RowId)
+);
+
+CREATE INDEX IX_Plate_Container ON assay.Plate(Container);
+
+ALTER TABLE assay.plate
+ ADD Modified TIMESTAMP,
+ ADD ModifiedBy USERID;
+
+ALTER TABLE assay.plate
+ ALTER Modified SET NOT NULL,
+ ALTER ModifiedBy SET NOT NULL;
+
+ALTER TABLE assay.plate
+ ADD CONSTRAINT uq_plate_lsid UNIQUE (lsid);
+
+-- plate template (not instances) names are unique in each container
+CREATE UNIQUE INDEX uq_plate_container_name_template ON assay.plate (container, name) WHERE template=true;
+
+CREATE TABLE assay.WellGroup
+(
+ RowId SERIAL,
+ PlateId INT NOT NULL,
+ LSID VARCHAR(200) NOT NULL,
+ Container ENTITYID NOT NULL,
+ Name VARCHAR(200) NULL,
+ Template BOOLEAN NOT NULL,
+ TypeName VARCHAR(50) NOT NULL,
+
+ CONSTRAINT PK_WellGroup PRIMARY KEY (RowId),
+ CONSTRAINT FK_WellGroup_Plate FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId)
+);
+
+CREATE INDEX IX_WellGroup_PlateId ON assay.WellGroup(PlateId);
+CREATE INDEX IX_WellGroup_Container ON assay.WellGroup(Container);
+
+ALTER TABLE assay.wellgroup
+ ADD CONSTRAINT uq_wellgroup_lsid UNIQUE (lsid);
+
+-- well group names must be unique within each well group type
+ALTER TABLE assay.wellgroup
+ ADD CONSTRAINT uq_wellgroup_plateid_typename_name UNIQUE (plateid, typename, name);
+
+CREATE TABLE assay.Well
+(
+ RowId SERIAL,
+ LSID VARCHAR(200) NOT NULL,
+ Container ENTITYID NOT NULL,
+ Value FLOAT NULL,
+ Dilution FLOAT NULL,
+ PlateId INT NOT NULL,
+ Row INT NOT NULL,
+ Col INT NOT NULL,
+
+ CONSTRAINT PK_Well PRIMARY KEY (RowId),
+ CONSTRAINT FK_Well_Plate FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId)
+);
+
+CREATE INDEX IX_Well_PlateId ON assay.Well(PlateId);
+CREATE INDEX IX_Well_Container ON assay.Well(Container);
+
+ALTER TABLE assay.well
+ ADD CONSTRAINT uq_well_lsid UNIQUE (lsid);
+
+-- each well position is unique on the plate
+ALTER TABLE assay.well
+ ADD CONSTRAINT uq_well_plateid_row_col UNIQUE (plateid, row, col);
+
+ALTER TABLE Assay.Well ADD COLUMN SampleId INTEGER NULL;
+ALTER TABLE Assay.Well ADD CONSTRAINT FK_SampleId_ExpMaterial FOREIGN KEY (SampleId) REFERENCES exp.material (RowId);
+
+CREATE TABLE assay.WellGroupPositions
+(
+ RowId SERIAL,
+ WellId INT NOT NULL,
+ WellGroupId INT NOT NULL,
+
+ CONSTRAINT PK_WellGroupPositions PRIMARY KEY (RowId),
+ CONSTRAINT FK_WellGroupPositions_Well FOREIGN KEY (WellId) REFERENCES assay.Well(RowId),
+ CONSTRAINT FK_WellGroupPositions_WellGroup FOREIGN KEY (WellGroupId) REFERENCES assay.WellGroup(RowId),
+ CONSTRAINT UQ_WellGroupPositions_WellGroup_Well UNIQUE (WellGroupId, WellId)
+);
+
+CREATE TABLE assay.PlateProperty
+(
+ RowId SERIAL,
+ PlateId INT NOT NULL,
+ PropertyId INT NOT NULL,
+ PropertyURI VARCHAR(300) NOT NULL,
+
+ CONSTRAINT PK_PlateProperty PRIMARY KEY (RowId),
+ CONSTRAINT UQ_PlateProperty_PlateId_PropertyId UNIQUE (PlateId, PropertyId),
+ CONSTRAINT FK_PlateProperty_PlateId FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId),
+ CONSTRAINT FK_PlateProperty_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor(PropertyId)
+);
+
+/* 24.xxx SQL scripts */
+
+CREATE TABLE assay.PlateSet
+(
+ RowId INT NOT NULL,
+ Name VARCHAR(200) NOT NULL,
+ Container ENTITYID NOT NULL,
+ Created TIMESTAMP NOT NULL,
+ CreatedBy USERID NOT NULL,
+ Modified TIMESTAMP NOT NULL,
+ ModifiedBy USERID NOT NULL,
+ Archived BOOLEAN NOT NULL DEFAULT FALSE,
+
+ CONSTRAINT PK_PlateSet PRIMARY KEY (RowId)
+);
+
+-- Insert a row into the plate set table for every plate in the system, store the plate row ID in the plate set table
+-- in order to create the FK from the plate to plate set table
+INSERT INTO assay.PlateSet (RowId, Name, Container, Created, CreatedBy, Modified, ModifiedBy)
+ SELECT RowId, 'TempPlateSet', Container, now(), CreatedBy, now(), ModifiedBy FROM assay.Plate;
+
+-- Add the plate set field to the plate table and populate it with the plate set row ID
+ALTER TABLE assay.Plate ADD COLUMN PlateSet INTEGER;
+UPDATE assay.Plate SET PlateSet = RowId;
+ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateSet FOREIGN KEY (PlateSet) REFERENCES assay.PlateSet (RowId);
+CREATE INDEX IX_Plate_PlateSet ON assay.Plate (PlateSet);
+
+CREATE TABLE assay.PlateType
+(
+ RowId SERIAL,
+ Rows INT NOT NULL,
+ Columns INT NOT NULL,
+ Description VARCHAR(300) NOT NULL,
+ Archived BOOLEAN NOT NULL DEFAULT FALSE,
+
+ CONSTRAINT PK_PlateType PRIMARY KEY (RowId),
+ CONSTRAINT UQ_PlateType_Rows_Cols UNIQUE (Rows, Columns)
+);
+
+-- @SkipOnEmptySchemasBegin
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (3, 4, '12 well (3x4)');
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (4, 6, '24 well (4x6)');
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well (6x8)');
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)');
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)');
+INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (32, 48, '1536 well (32x48)', TRUE);
+INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)', TRUE);
+-- @SkipOnEmptySchemasEnd
+
+-- Rename type column to assayType
+ALTER TABLE assay.Plate RENAME COLUMN Type TO AssayType;
+-- Add plateType as a FK to assay.PlateType
+ALTER TABLE assay.Plate ADD COLUMN PlateType INTEGER;
+ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateType FOREIGN KEY (PlateType) REFERENCES assay.PlateType (RowId);
+
+-- Add ID and description columns to Plate and PlateSet tables
+ALTER TABLE assay.Plate ADD COLUMN PlateId VARCHAR(200);
+ALTER TABLE assay.Plate ADD COLUMN Description VARCHAR(300);
+ALTER TABLE assay.PlateSet ADD COLUMN PlateSetId VARCHAR(200);
+ALTER TABLE assay.PlateSet ADD COLUMN Description VARCHAR(300);
+
+-- Most existing plate sets will have a generated name, but mutated ones will get fixed up by the java upgrade script
+UPDATE assay.PlateSet SET PlateSetId = Name;
+
+UPDATE assay.Plate
+SET PlateType =
+ CASE
+ WHEN (Rows = 3 AND Columns = 4) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 3 AND Columns = 4)
+ WHEN (Rows = 4 AND Columns = 6) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 4 AND Columns = 6)
+ WHEN (Rows = 6 AND Columns = 8) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 6 AND Columns = 8)
+ WHEN (Rows = 8 AND Columns = 12) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 8 AND Columns = 12)
+ WHEN (Rows = 16 AND Columns = 24) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 16 AND Columns = 24)
+ WHEN (Rows = 32 AND Columns = 48) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 32 AND Columns = 48)
+ ELSE (SELECT RowId FROM assay.PlateType WHERE Rows = 0 AND Columns = 0)
+ END
+WHERE PlateType IS NULL;
+
+ALTER TABLE assay.Plate ALTER COLUMN PlateType SET NOT NULL;
+ALTER TABLE assay.Plate DROP COLUMN Rows;
+ALTER TABLE assay.Plate DROP COLUMN Columns;
+
+-- finalize plate and plateSet ID columns
+ALTER TABLE assay.Plate ALTER COLUMN PlateId SET NOT NULL;
+ALTER TABLE assay.Plate ADD CONSTRAINT UQ_Plate_PlateId UNIQUE (PlateId);
+
+ALTER TABLE assay.PlateSet ALTER COLUMN PlateSetId SET NOT NULL;
+ALTER TABLE assay.PlateSet ADD CONSTRAINT UQ_PlateSet_PlateSetId UNIQUE (PlateSetId);
+
+ALTER TABLE assay.PlateSet ADD COLUMN Type VARCHAR(64);
+ALTER TABLE assay.PlateSet ADD COLUMN RootPlateSetId INT;
+ALTER TABLE assay.PlateSet ADD COLUMN PrimaryPlateSetId INT;
+ALTER TABLE assay.PlateSet ADD CONSTRAINT FK_PlateSet_RootPlateSetId FOREIGN KEY (RootPlateSetId) REFERENCES assay.PlateSet (RowId);
+ALTER TABLE assay.PlateSet ADD CONSTRAINT FK_PlateSet_PrimaryPlateSetId FOREIGN KEY (PrimaryPlateSetId) REFERENCES assay.PlateSet (RowId);
+
+-- Update all pre-existing plate sets to type "assay"
+UPDATE assay.PlateSet SET type = 'assay';
+
+ALTER TABLE assay.PlateSet ALTER COLUMN Type SET NOT NULL;
+
+CREATE TABLE assay.PlateSetEdge
+(
+ FromPlateSetId INT NOT NULL,
+ ToPlateSetId INT NOT NULL,
+ RootPlateSetId INT NOT NULL,
+
+ CONSTRAINT FK_PlateSet_FromPlate FOREIGN KEY (FromPlateSetId) REFERENCES assay.PlateSet (RowId),
+ CONSTRAINT FK_PlateSet_ToPlate FOREIGN KEY (ToPlateSetId) REFERENCES assay.PlateSet (RowId),
+ CONSTRAINT FK_PlateSet_RootPlate FOREIGN KEY (RootPlateSetId) REFERENCES assay.PlateSet (RowId),
+ CONSTRAINT UQ_PlateSetEdge_FromPlate_ToPlate UNIQUE (FromPlateSetId, ToPlateSetId)
+);
+
+CREATE INDEX IX_PlateSetEdge_FromPlateSetId ON assay.PlateSetEdge (FromPlateSetId);
+CREATE INDEX IX_PlateSetEdge_ToPlateSetId ON assay.PlateSetEdge (ToPlateSetId);
+CREATE INDEX IX_PlateSetEdge_RootPlateSetId ON assay.PlateSetEdge (RootPlateSetId);
+
+CREATE TABLE assay.Hit
+(
+ RowId SERIAL,
+ Container ENTITYID NOT NULL,
+ ProtocolId INT NOT NULL,
+ ResultId INT NOT NULL,
+ RunId INT NOT NULL,
+ WellLsid VARCHAR(200) NOT NULL,
+
+ CONSTRAINT PK_Hit PRIMARY KEY (RowId),
+ CONSTRAINT FK_Hit_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId),
+ CONSTRAINT FK_Protocol_ProtocolId FOREIGN KEY (ProtocolId) REFERENCES exp.Protocol (RowId),
+ CONSTRAINT FK_Run_RunId FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId),
+ CONSTRAINT FK_Well_WellLsid FOREIGN KEY (WellLsid) REFERENCES assay.Well (Lsid),
+ CONSTRAINT UQ_Hit_RunId_ResultId UNIQUE (RunId, ResultId)
+);
+
+ALTER TABLE assay.Hit ADD COLUMN PlateSetPath VARCHAR (4000);
+
+ALTER TABLE assay.Hit ALTER COLUMN PlateSetPath SET NOT NULL;
+
+ALTER TABLE assay.PlateSet ADD COLUMN Template BOOLEAN NOT NULL DEFAULT FALSE;
+UPDATE assay.Plate SET Template = False WHERE Template = True;
+
+ALTER TABLE assay.Plate ADD COLUMN Archived BOOLEAN NOT NULL DEFAULT FALSE;
+
+UPDATE assay.Plate SET AssayType = 'Standard' WHERE AssayType IS NULL;
+ALTER TABLE assay.Plate ALTER COLUMN AssayType SET NOT NULL;
+
+-- Add index on assay.Well.SampleId to improve performance of DELETE operation on exp.Material table.
+CREATE INDEX IX_Well_SampleId ON assay.Well (SampleId);
+
+-- Add index on assay.WellGroupPositions.WellId to improve performance of DELETE operation on assay.Well table.
+CREATE INDEX IX_WellGroupPositions_WellId ON assay.WellGroupPositions (WellId);
+
+ALTER TABLE assay.plate ADD Barcode VARCHAR(255);
+ALTER TABLE assay.plate ADD CONSTRAINT UQ_Barcode UNIQUE (Barcode);
+
+UPDATE assay.plate SET Barcode = LPAD(rowid::text, 9, '0') WHERE plate.Barcode IS NULL AND plate.template IS FALSE;
+
+ALTER TABLE assay.plate ADD CONSTRAINT check_template_true_barcode_null CHECK (NOT plate.template OR plate.Barcode IS NULL);
+
+-- Specify plate metadata columns on the plate set rather than the individual plates
+CREATE TABLE assay.PlateSetProperty
+(
+ RowId SERIAL,
+ PlateSetId INT NOT NULL,
+ PropertyId INT NOT NULL,
+ PropertyURI VARCHAR(300) NOT NULL,
+
+ CONSTRAINT PK_PlateSetProperty PRIMARY KEY (RowId),
+ CONSTRAINT UQ_PlateSetProperty_PlateSetId_PropertyId UNIQUE (PlateSetId, PropertyId),
+ CONSTRAINT FK_PlateSetProperty_PlateSetId FOREIGN KEY (PlateSetId) REFERENCES assay.PlateSet(RowId) ON DELETE CASCADE,
+ CONSTRAINT FK_PlateSetProperty_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor(PropertyId) ON DELETE CASCADE
+);
+
+INSERT INTO assay.PlateSetProperty (PlateSetId, PropertyId, PropertyURI)
+SELECT
+ PL.PlateSet AS PlateSetId,
+ PP.PropertyId,
+ PP.PropertyURI
+FROM assay.PlateProperty AS PP
+INNER JOIN assay.Plate AS PL ON PP.PlateId = PL.RowId
+GROUP BY PlateSetId, PropertyId, PropertyURI
+ORDER BY PlateSetId, PropertyId;
+
+DROP TABLE assay.PlateProperty;
+
+ALTER TABLE assay.platesetproperty
+ ADD COLUMN FieldKey VARCHAR(255);
+
+ALTER TABLE assay.platesetproperty
+ ADD CONSTRAINT either_identifier
+ CHECK (PropertyURI IS NOT NULL OR FieldKey IS NOT NULL);
+
+ALTER TABLE assay.platesetproperty ALTER COLUMN PropertyURI DROP NOT NULL;
+ALTER TABLE assay.platesetproperty ALTER COLUMN PropertyId DROP NOT NULL;
+
+ALTER TABLE assay.plateset ADD COLUMN LSID LSIDtype;
+
+ALTER TABLE assay.plateset ALTER COLUMN LSID SET NOT NULL;
+
+CREATE TABLE assay.FilterCriteria
+(
+ RowId SERIAL,
+ PropertyId INT NOT NULL,
+ ReferencePropertyId INT NOT NULL,
+ DomainId INT NOT NULL,
+ Operation VARCHAR(50) NOT NULL,
+ Value VARCHAR(4000) NULL,
+
+ CONSTRAINT PK_FilterCriteria PRIMARY KEY (RowId),
+ CONSTRAINT FK_FilterCriteria_PropertyDescriptor FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) ON DELETE CASCADE,
+ CONSTRAINT FK_FilterCriteria_PropertyDescriptor_Reference FOREIGN KEY (ReferencePropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) ON DELETE CASCADE,
+ CONSTRAINT FK_FilterCriteria_DomainDescriptor FOREIGN KEY (DomainId) REFERENCES exp.DomainDescriptor (DomainId) ON DELETE CASCADE
+);
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.000-24.001.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.000-24.001.sql
deleted file mode 100644
index ea78b142261..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.000-24.001.sql
+++ /dev/null
@@ -1,27 +0,0 @@
-CREATE TABLE assay.PlateSet
-(
- RowId INT NOT NULL,
- Name VARCHAR(200) NOT NULL,
- Container ENTITYID NOT NULL,
- Created TIMESTAMP NOT NULL,
- CreatedBy USERID NOT NULL,
- Modified TIMESTAMP NOT NULL,
- ModifiedBy USERID NOT NULL,
- Archived BOOLEAN NOT NULL DEFAULT FALSE,
-
- CONSTRAINT PK_PlateSet PRIMARY KEY (RowId)
-);
-
--- Insert a row into the plate set table for every plate in the system, store the plate row ID in the plate set table
--- in order to create the FK from the plate to plate set table
-INSERT INTO assay.PlateSet (RowId, Name, Container, Created, CreatedBy, Modified, ModifiedBy)
- SELECT RowId, 'TempPlateSet', Container, now(), CreatedBy, now(), ModifiedBy FROM assay.Plate;
-
--- Add the plate set field to the plate table and populate it with the plate set row ID
-ALTER TABLE assay.Plate ADD COLUMN PlateSet INTEGER;
-UPDATE assay.Plate SET PlateSet = RowId;
-ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateSet FOREIGN KEY (PlateSet) REFERENCES assay.PlateSet (RowId);
-CREATE INDEX IX_Plate_PlateSet ON assay.Plate (PlateSet);
-
--- Run the java upgrade script to update plate set and plate tables to create the name expression based name values
-SELECT core.executeJavaUpgradeCode('updatePlateSetNames');
\ No newline at end of file
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql
deleted file mode 100644
index d86ed7e0ad6..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.001-24.002.sql
+++ /dev/null
@@ -1,63 +0,0 @@
-CREATE TABLE assay.PlateType
-(
- RowId SERIAL,
- Rows INT NOT NULL,
- Columns INT NOT NULL,
- Description VARCHAR(300) NOT NULL,
- Archived BOOLEAN NOT NULL DEFAULT FALSE,
-
- CONSTRAINT PK_PlateType PRIMARY KEY (RowId),
- CONSTRAINT UQ_PlateType_Rows_Cols UNIQUE (Rows, Columns)
-);
-
--- @SkipOnEmptySchemasBegin
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (3, 4, '12 well (3x4)');
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (4, 6, '24 well (4x6)');
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well (6x8)');
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)');
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)');
-INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (32, 48, '1536 well (32x48)', TRUE);
-INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)', TRUE);
--- @SkipOnEmptySchemasEnd
-
--- Rename type column to assayType
-ALTER TABLE assay.Plate RENAME COLUMN Type TO AssayType;
--- Add plateType as a FK to assay.PlateType
-ALTER TABLE assay.Plate ADD COLUMN PlateType INTEGER;
-ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateType FOREIGN KEY (PlateType) REFERENCES assay.PlateType (RowId);
-
--- Add ID and description columns to Plate and PlateSet tables
-ALTER TABLE assay.Plate ADD COLUMN PlateId VARCHAR(200);
-ALTER TABLE assay.Plate ADD COLUMN Description VARCHAR(300);
-ALTER TABLE assay.PlateSet ADD COLUMN PlateSetId VARCHAR(200);
-ALTER TABLE assay.PlateSet ADD COLUMN Description VARCHAR(300);
-
--- Most existing plate sets will have a generated name, but mutated ones will get fixed up by the java upgrade script
-UPDATE assay.PlateSet SET PlateSetId = Name;
-
-UPDATE assay.Plate
-SET PlateType =
- CASE
- WHEN (Rows = 3 AND Columns = 4) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 3 AND Columns = 4)
- WHEN (Rows = 4 AND Columns = 6) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 4 AND Columns = 6)
- WHEN (Rows = 6 AND Columns = 8) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 6 AND Columns = 8)
- WHEN (Rows = 8 AND Columns = 12) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 8 AND Columns = 12)
- WHEN (Rows = 16 AND Columns = 24) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 16 AND Columns = 24)
- WHEN (Rows = 32 AND Columns = 48) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 32 AND Columns = 48)
- ELSE (SELECT RowId FROM assay.PlateType WHERE Rows = 0 AND Columns = 0)
- END
-WHERE PlateType IS NULL;
-
-ALTER TABLE assay.Plate ALTER COLUMN PlateType SET NOT NULL;
-ALTER TABLE assay.Plate DROP COLUMN Rows;
-ALTER TABLE assay.Plate DROP COLUMN Columns;
-
--- upgrade script to initialize plate and plateSet IDs
-SELECT core.executeJavaUpgradeCode('initializePlateAndPlateSetIDs');
-
--- finalize plate and plateSet ID columns
-ALTER TABLE assay.Plate ALTER COLUMN PlateId SET NOT NULL;
-ALTER TABLE assay.Plate ADD CONSTRAINT UQ_Plate_PlateId UNIQUE (PlateId);
-
-ALTER TABLE assay.PlateSet ALTER COLUMN PlateSetId SET NOT NULL;
-ALTER TABLE assay.PlateSet ADD CONSTRAINT UQ_PlateSet_PlateSetId UNIQUE (PlateSetId);
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.002-24.003.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.002-24.003.sql
deleted file mode 100644
index a3cba9f6605..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.002-24.003.sql
+++ /dev/null
@@ -1,5 +0,0 @@
--- Provisioned schema used by PlateMetadataDomainKind
-CREATE SCHEMA assaywell;
-
--- upgrade script to initialize plate and plateSet IDs
-SELECT core.executeJavaUpgradeCode('deletePlateVocabDomains');
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.003-24.004.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.003-24.004.sql
deleted file mode 100644
index 60ff87df5e4..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.003-24.004.sql
+++ /dev/null
@@ -1,27 +0,0 @@
-ALTER TABLE assay.PlateSet ADD COLUMN Type VARCHAR(64);
-ALTER TABLE assay.PlateSet ADD COLUMN RootPlateSetId INT;
-ALTER TABLE assay.PlateSet ADD COLUMN PrimaryPlateSetId INT;
-ALTER TABLE assay.PlateSet ADD CONSTRAINT FK_PlateSet_RootPlateSetId FOREIGN KEY (RootPlateSetId) REFERENCES assay.PlateSet (RowId);
-ALTER TABLE assay.PlateSet ADD CONSTRAINT FK_PlateSet_PrimaryPlateSetId FOREIGN KEY (PrimaryPlateSetId) REFERENCES assay.PlateSet (RowId);
-
--- Update all pre-existing plate sets to type "assay"
-UPDATE assay.PlateSet SET type = 'assay';
-
-ALTER TABLE assay.PlateSet ALTER COLUMN Type SET NOT NULL;
-
-CREATE TABLE assay.PlateSetEdge
-(
- FromPlateSetId INT NOT NULL,
- ToPlateSetId INT NOT NULL,
- RootPlateSetId INT NOT NULL,
-
- CONSTRAINT FK_PlateSet_FromPlate FOREIGN KEY (FromPlateSetId) REFERENCES assay.PlateSet (RowId),
- CONSTRAINT FK_PlateSet_ToPlate FOREIGN KEY (ToPlateSetId) REFERENCES assay.PlateSet (RowId),
- CONSTRAINT FK_PlateSet_RootPlate FOREIGN KEY (RootPlateSetId) REFERENCES assay.PlateSet (RowId),
- CONSTRAINT UQ_PlateSetEdge_FromPlate_ToPlate UNIQUE (FromPlateSetId, ToPlateSetId)
-);
-
-CREATE INDEX IX_PlateSetEdge_FromPlateSetId ON assay.PlateSetEdge (FromPlateSetId);
-CREATE INDEX IX_PlateSetEdge_ToPlateSetId ON assay.PlateSetEdge (ToPlateSetId);
-CREATE INDEX IX_PlateSetEdge_RootPlateSetId ON assay.PlateSetEdge (RootPlateSetId);
-
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.004-24.005.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.004-24.005.sql
deleted file mode 100644
index ce43a9e13b0..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.004-24.005.sql
+++ /dev/null
@@ -1,16 +0,0 @@
-CREATE TABLE assay.Hit
-(
- RowId SERIAL,
- Container ENTITYID NOT NULL,
- ProtocolId INT NOT NULL,
- ResultId INT NOT NULL,
- RunId INT NOT NULL,
- WellLsid VARCHAR(200) NOT NULL,
-
- CONSTRAINT PK_Hit PRIMARY KEY (RowId),
- CONSTRAINT FK_Hit_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId),
- CONSTRAINT FK_Protocol_ProtocolId FOREIGN KEY (ProtocolId) REFERENCES exp.Protocol (RowId),
- CONSTRAINT FK_Run_RunId FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId),
- CONSTRAINT FK_Well_WellLsid FOREIGN KEY (WellLsid) REFERENCES assay.Well (Lsid),
- CONSTRAINT UQ_Hit_RunId_ResultId UNIQUE (RunId, ResultId)
-);
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.005-24.006.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.005-24.006.sql
deleted file mode 100644
index c165bc5d841..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.005-24.006.sql
+++ /dev/null
@@ -1,6 +0,0 @@
-ALTER TABLE assay.Hit ADD COLUMN PlateSetPath VARCHAR (4000);
-
--- Populate paths of pre-existing hits
-SELECT core.executeJavaUpgradeCode('populatePlateSetPaths');
-
-ALTER TABLE assay.Hit ALTER COLUMN PlateSetPath SET NOT NULL;
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.006-24.007.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.006-24.007.sql
deleted file mode 100644
index 2c1f6337fc3..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.006-24.007.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-ALTER TABLE assay.PlateSet ADD COLUMN Template BOOLEAN NOT NULL DEFAULT FALSE;
-UPDATE assay.Plate SET Template = False WHERE Template = True;
-
-ALTER TABLE assay.Plate ADD COLUMN Archived BOOLEAN NOT NULL DEFAULT FALSE;
-
-UPDATE assay.Plate SET AssayType = 'Standard' WHERE AssayType IS NULL;
-ALTER TABLE assay.Plate ALTER COLUMN AssayType SET NOT NULL;
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.007-24.008.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.007-24.008.sql
deleted file mode 100644
index c413b0f4d93..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.007-24.008.sql
+++ /dev/null
@@ -1 +0,0 @@
-SELECT core.executeJavaUpgradeCode('populatePlateWellTypes');
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.008-24.009.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.008-24.009.sql
deleted file mode 100644
index 60acb08af3b..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.008-24.009.sql
+++ /dev/null
@@ -1,5 +0,0 @@
--- Add index on assay.Well.SampleId to improve performance of DELETE operation on exp.Material table.
-CREATE INDEX IX_Well_SampleId ON assay.Well (SampleId);
-
--- Add index on assay.WellGroupPositions.WellId to improve performance of DELETE operation on assay.Well table.
-CREATE INDEX IX_WellGroupPositions_WellId ON assay.WellGroupPositions (WellId);
\ No newline at end of file
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.009-24.010.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.009-24.010.sql
deleted file mode 100644
index cbed98e8518..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.009-24.010.sql
+++ /dev/null
@@ -1 +0,0 @@
-SELECT core.executeJavaUpgradeCode('renameWellMetadataFields');
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.010-24.011.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.010-24.011.sql
deleted file mode 100644
index 7216742b2f4..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.010-24.011.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-ALTER TABLE assay.plate ADD Barcode VARCHAR(255);
-ALTER TABLE assay.plate ADD CONSTRAINT UQ_Barcode UNIQUE (Barcode);
-
-UPDATE assay.plate SET Barcode = LPAD(rowid::text, 9, '0') WHERE plate.Barcode IS NULL AND plate.template IS FALSE;
-
-ALTER TABLE assay.plate ADD CONSTRAINT check_template_true_barcode_null CHECK (NOT plate.template OR plate.Barcode IS NULL);
-
-SELECT core.executeJavaUpgradeCode('updateBarcodeSequence');
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.011-24.012.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.011-24.012.sql
deleted file mode 100644
index 63cef693456..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.011-24.012.sql
+++ /dev/null
@@ -1,25 +0,0 @@
--- Specify plate metadata columns on the plate set rather than the individual plates
-CREATE TABLE assay.PlateSetProperty
-(
- RowId SERIAL,
- PlateSetId INT NOT NULL,
- PropertyId INT NOT NULL,
- PropertyURI VARCHAR(300) NOT NULL,
-
- CONSTRAINT PK_PlateSetProperty PRIMARY KEY (RowId),
- CONSTRAINT UQ_PlateSetProperty_PlateSetId_PropertyId UNIQUE (PlateSetId, PropertyId),
- CONSTRAINT FK_PlateSetProperty_PlateSetId FOREIGN KEY (PlateSetId) REFERENCES assay.PlateSet(RowId) ON DELETE CASCADE,
- CONSTRAINT FK_PlateSetProperty_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor(PropertyId) ON DELETE CASCADE
-);
-
-INSERT INTO assay.PlateSetProperty (PlateSetId, PropertyId, PropertyURI)
-SELECT
- PL.PlateSet AS PlateSetId,
- PP.PropertyId,
- PP.PropertyURI
-FROM assay.PlateProperty AS PP
-INNER JOIN assay.Plate AS PL ON PP.PlateId = PL.RowId
-GROUP BY PlateSetId, PropertyId, PropertyURI
-ORDER BY PlateSetId, PropertyId;
-
-DROP TABLE assay.PlateProperty;
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.012-24.013.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.012-24.013.sql
deleted file mode 100644
index 614293a5595..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.012-24.013.sql
+++ /dev/null
@@ -1,11 +0,0 @@
-ALTER TABLE assay.platesetproperty
- ADD COLUMN FieldKey VARCHAR(255);
-
-ALTER TABLE assay.platesetproperty
- ADD CONSTRAINT either_identifier
- CHECK (PropertyURI IS NOT NULL OR FieldKey IS NOT NULL);
-
-ALTER TABLE assay.platesetproperty ALTER COLUMN PropertyURI DROP NOT NULL;
-ALTER TABLE assay.platesetproperty ALTER COLUMN PropertyId DROP NOT NULL;
-
-SELECT core.executeJavaUpgradeCode('updateBuiltInColumns');
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.013-24.014.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.013-24.014.sql
deleted file mode 100644
index cfbd66864a5..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.013-24.014.sql
+++ /dev/null
@@ -1 +0,0 @@
-SELECT core.executeJavaUpgradeCode('initializeWellExclusions');
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.014-24.015.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.014-24.015.sql
deleted file mode 100644
index a6c34330c03..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.014-24.015.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-ALTER TABLE assay.plateset ADD COLUMN LSID LSIDtype;
-
-SELECT core.executeJavaUpgradeCode('addLsidToPlateSets');
-
-ALTER TABLE assay.plateset ALTER COLUMN LSID SET NOT NULL;
diff --git a/assay/resources/schemas/dbscripts/postgresql/assay-24.015-24.016.sql b/assay/resources/schemas/dbscripts/postgresql/assay-24.015-24.016.sql
deleted file mode 100644
index fa1a4ccd8a3..00000000000
--- a/assay/resources/schemas/dbscripts/postgresql/assay-24.015-24.016.sql
+++ /dev/null
@@ -1,16 +0,0 @@
-CREATE TABLE assay.FilterCriteria
-(
- RowId SERIAL,
- PropertyId INT NOT NULL,
- ReferencePropertyId INT NOT NULL,
- DomainId INT NOT NULL,
- Operation VARCHAR(50) NOT NULL,
- Value VARCHAR(4000) NULL,
-
- CONSTRAINT PK_FilterCriteria PRIMARY KEY (RowId),
- CONSTRAINT FK_FilterCriteria_PropertyDescriptor FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) ON DELETE CASCADE,
- CONSTRAINT FK_FilterCriteria_PropertyDescriptor_Reference FOREIGN KEY (ReferencePropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) ON DELETE CASCADE,
- CONSTRAINT FK_FilterCriteria_DomainDescriptor FOREIGN KEY (DomainId) REFERENCES exp.DomainDescriptor (DomainId) ON DELETE CASCADE
-);
-
-SELECT core.executeJavaUpgradeCode('initializeHitSelectionCriteria');
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-0.000-24.000.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-0.000-24.000.sql
deleted file mode 100644
index a3207caf9eb..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-0.000-24.000.sql
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- For LabKey 19.2 and earlier, the assayresult schema and the Plate, WellGroup, and Well tables were managed by the
- study module. As of 19.3, the assay module now manages these objects, with the tables moving from the "study" schema
- to the new "assay" schema.
- */
-
-CREATE SCHEMA assay
-GO
-CREATE SCHEMA assayresult
-GO
-
-CREATE TABLE assay.Plate
-(
- RowId INT IDENTITY(1,1),
- LSID NVARCHAR(200) NOT NULL,
- Container ENTITYID NOT NULL,
- Name NVARCHAR(200) NULL,
- CreatedBy USERID NOT NULL,
- Created DATETIME NOT NULL,
- Template BIT NOT NULL,
- DataFileId ENTITYID,
- Rows INT NOT NULL,
- Columns INT NOT NULL,
- Type NVARCHAR(200),
-
- CONSTRAINT PK_Plate PRIMARY KEY (RowId)
-);
-
-CREATE INDEX IX_Plate_Container ON assay.Plate(Container);
-
-ALTER TABLE assay.plate ADD
- Modified DATETIME,
- ModifiedBy USERID;
-
-ALTER TABLE assay.plate ALTER COLUMN Modified DATETIME NOT NULL;
-ALTER TABLE assay.plate ALTER COLUMN ModifiedBy USERID NOT NULL;
-
-ALTER TABLE assay.plate
- ADD CONSTRAINT uq_plate_lsid UNIQUE (lsid);
-
--- plate template (not instances) names are unique in each container
-CREATE UNIQUE INDEX uq_plate_container_name_template ON assay.plate (container, name) WHERE template=1;
-
-CREATE TABLE assay.WellGroup
-(
- RowId INT IDENTITY(1,1),
- PlateId INT NOT NULL,
- LSID NVARCHAR(200) NOT NULL,
- Container ENTITYID NOT NULL,
- Name NVARCHAR(200) NULL,
- Template BIT NOT NULL,
- TypeName NVARCHAR(50) NOT NULL,
-
- CONSTRAINT PK_WellGroup PRIMARY KEY (RowId),
- CONSTRAINT FK_WellGroup_Plate FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId)
-);
-
-CREATE INDEX IX_WellGroup_PlateId ON assay.WellGroup(PlateId);
-CREATE INDEX IX_WellGroup_Container ON assay.WellGroup(Container);
-
-ALTER TABLE assay.wellgroup
- ADD CONSTRAINT uq_wellgroup_lsid UNIQUE (lsid);
-
--- well group names must be unique within each well group type
-ALTER TABLE assay.wellgroup
- ADD CONSTRAINT uq_wellgroup_plateid_typename_name UNIQUE (plateid, typename, name);
-
-CREATE TABLE assay.Well
-(
- RowId INT IDENTITY(1,1),
- LSID NVARCHAR(200) NOT NULL,
- Container ENTITYID NOT NULL,
- Value FLOAT NULL,
- Dilution FLOAT NULL,
- PlateId INT NOT NULL,
- Row INT NOT NULL,
- Col INT NOT NULL,
-
- CONSTRAINT PK_Well PRIMARY KEY (RowId),
- CONSTRAINT FK_Well_Plate FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId)
-);
-
-CREATE INDEX IX_Well_PlateId ON assay.Well(PlateId);
-CREATE INDEX IX_Well_Container ON assay.Well(Container);
-
-ALTER TABLE assay.well
- ADD CONSTRAINT uq_well_lsid UNIQUE (lsid);
-
--- each well position is unique on the plate
-ALTER TABLE assay.well
- ADD CONSTRAINT uq_well_plateid_row_col UNIQUE (plateid, row, col);
-
-ALTER TABLE Assay.Well ADD SampleId INTEGER NULL;
-ALTER TABLE Assay.Well ADD CONSTRAINT FK_SampleId_ExpMaterial FOREIGN KEY (SampleId) REFERENCES exp.material (RowId);
-
-CREATE TABLE assay.WellGroupPositions
-(
- RowId INT IDENTITY(1,1) NOT NULL,
- WellId INT NOT NULL,
- WellGroupId INT NOT NULL,
-
- CONSTRAINT PK_WellGroupPositions PRIMARY KEY (RowId),
- CONSTRAINT FK_WellGroupPositions_Well FOREIGN KEY (WellId) REFERENCES assay.Well(RowId),
- CONSTRAINT FK_WellGroupPositions_WellGroup FOREIGN KEY (WellGroupId) REFERENCES assay.WellGroup(RowId),
- CONSTRAINT UQ_WellGroupPositions_WellGroup_Well UNIQUE (WellGroupId, WellId)
-);
-
-CREATE TABLE assay.PlateProperty
-(
- RowId INT IDENTITY(1,1),
- PlateId INT NOT NULL,
- PropertyId INT NOT NULL,
- PropertyURI NVARCHAR(300) NOT NULL,
-
- CONSTRAINT PK_PlateProperty PRIMARY KEY (RowId),
- CONSTRAINT UQ_PlateProperty_PlateId_PropertyId UNIQUE (PlateId, PropertyId),
- CONSTRAINT FK_PlateProperty_PlateId FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId),
- CONSTRAINT FK_PlateProperty_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor(PropertyId)
-);
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-0.000-25.000.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-0.000-25.000.sql
new file mode 100644
index 00000000000..d7d9fc6313f
--- /dev/null
+++ b/assay/resources/schemas/dbscripts/sqlserver/assay-0.000-25.000.sql
@@ -0,0 +1,356 @@
+/*
+ For LabKey 19.2 and earlier, the assayresult schema and the Plate, WellGroup, and Well tables were managed by the
+ study module. As of 19.3, the assay module now manages these objects, with the tables moving from the "study" schema
+ to the new "assay" schema.
+ */
+
+CREATE SCHEMA assay
+GO
+CREATE SCHEMA assayresult
+GO
+-- Provisioned schema used by PlateMetadataDomainKind
+CREATE SCHEMA assaywell;
+GO
+
+CREATE TABLE assay.Plate
+(
+ RowId INT IDENTITY(1,1),
+ LSID NVARCHAR(200) NOT NULL,
+ Container ENTITYID NOT NULL,
+ Name NVARCHAR(200) NULL,
+ CreatedBy USERID NOT NULL,
+ Created DATETIME NOT NULL,
+ Template BIT NOT NULL,
+ DataFileId ENTITYID,
+ Rows INT NOT NULL,
+ Columns INT NOT NULL,
+ Type NVARCHAR(200),
+
+ CONSTRAINT PK_Plate PRIMARY KEY (RowId)
+);
+
+CREATE INDEX IX_Plate_Container ON assay.Plate(Container);
+
+ALTER TABLE assay.plate ADD
+ Modified DATETIME,
+ ModifiedBy USERID;
+
+ALTER TABLE assay.plate ALTER COLUMN Modified DATETIME NOT NULL;
+ALTER TABLE assay.plate ALTER COLUMN ModifiedBy USERID NOT NULL;
+
+ALTER TABLE assay.plate
+ ADD CONSTRAINT uq_plate_lsid UNIQUE (lsid);
+
+-- plate template (not instances) names are unique in each container
+CREATE UNIQUE INDEX uq_plate_container_name_template ON assay.plate (container, name) WHERE template=1;
+
+CREATE TABLE assay.WellGroup
+(
+ RowId INT IDENTITY(1,1),
+ PlateId INT NOT NULL,
+ LSID NVARCHAR(200) NOT NULL,
+ Container ENTITYID NOT NULL,
+ Name NVARCHAR(200) NULL,
+ Template BIT NOT NULL,
+ TypeName NVARCHAR(50) NOT NULL,
+
+ CONSTRAINT PK_WellGroup PRIMARY KEY (RowId),
+ CONSTRAINT FK_WellGroup_Plate FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId)
+);
+
+CREATE INDEX IX_WellGroup_PlateId ON assay.WellGroup(PlateId);
+CREATE INDEX IX_WellGroup_Container ON assay.WellGroup(Container);
+
+ALTER TABLE assay.wellgroup
+ ADD CONSTRAINT uq_wellgroup_lsid UNIQUE (lsid);
+
+-- well group names must be unique within each well group type
+ALTER TABLE assay.wellgroup
+ ADD CONSTRAINT uq_wellgroup_plateid_typename_name UNIQUE (plateid, typename, name);
+
+CREATE TABLE assay.Well
+(
+ RowId INT IDENTITY(1,1),
+ LSID NVARCHAR(200) NOT NULL,
+ Container ENTITYID NOT NULL,
+ Value FLOAT NULL,
+ Dilution FLOAT NULL,
+ PlateId INT NOT NULL,
+ Row INT NOT NULL,
+ Col INT NOT NULL,
+
+ CONSTRAINT PK_Well PRIMARY KEY (RowId),
+ CONSTRAINT FK_Well_Plate FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId)
+);
+
+CREATE INDEX IX_Well_PlateId ON assay.Well(PlateId);
+CREATE INDEX IX_Well_Container ON assay.Well(Container);
+
+ALTER TABLE assay.well
+ ADD CONSTRAINT uq_well_lsid UNIQUE (lsid);
+
+-- each well position is unique on the plate
+ALTER TABLE assay.well
+ ADD CONSTRAINT uq_well_plateid_row_col UNIQUE (plateid, row, col);
+
+ALTER TABLE Assay.Well ADD SampleId INTEGER NULL;
+ALTER TABLE Assay.Well ADD CONSTRAINT FK_SampleId_ExpMaterial FOREIGN KEY (SampleId) REFERENCES exp.material (RowId);
+
+CREATE TABLE assay.WellGroupPositions
+(
+ RowId INT IDENTITY(1,1) NOT NULL,
+ WellId INT NOT NULL,
+ WellGroupId INT NOT NULL,
+
+ CONSTRAINT PK_WellGroupPositions PRIMARY KEY (RowId),
+ CONSTRAINT FK_WellGroupPositions_Well FOREIGN KEY (WellId) REFERENCES assay.Well(RowId),
+ CONSTRAINT FK_WellGroupPositions_WellGroup FOREIGN KEY (WellGroupId) REFERENCES assay.WellGroup(RowId),
+ CONSTRAINT UQ_WellGroupPositions_WellGroup_Well UNIQUE (WellGroupId, WellId)
+);
+
+CREATE TABLE assay.PlateProperty
+(
+ RowId INT IDENTITY(1,1),
+ PlateId INT NOT NULL,
+ PropertyId INT NOT NULL,
+ PropertyURI NVARCHAR(300) NOT NULL,
+
+ CONSTRAINT PK_PlateProperty PRIMARY KEY (RowId),
+ CONSTRAINT UQ_PlateProperty_PlateId_PropertyId UNIQUE (PlateId, PropertyId),
+ CONSTRAINT FK_PlateProperty_PlateId FOREIGN KEY (PlateId) REFERENCES assay.Plate(RowId),
+ CONSTRAINT FK_PlateProperty_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor(PropertyId)
+);
+
+/* 24.xxx SQL scripts */
+
+CREATE TABLE assay.PlateSet
+(
+ RowId INT NOT NULL,
+ Name NVARCHAR(200) NOT NULL,
+ Container ENTITYID NOT NULL,
+ Created DATETIME NOT NULL,
+ CreatedBy USERID NOT NULL,
+ Modified DATETIME NOT NULL,
+ ModifiedBy USERID NOT NULL,
+ Archived BIT NOT NULL DEFAULT 0,
+
+ CONSTRAINT PK_PlateSet PRIMARY KEY (RowId)
+);
+
+-- Insert a row into the plate set table for every plate in the system, store the plate row ID in the plate set table
+-- in order to create the FK from the plate to plate set table
+INSERT INTO assay.PlateSet (RowId, Name, Container, Created, CreatedBy, Modified, ModifiedBy)
+SELECT RowId, 'TempPlateSet', Container, getdate(), CreatedBy, getdate(), ModifiedBy FROM assay.Plate;
+
+-- Add the plate set field to the plate table and populate it with the plate set row ID
+ALTER TABLE assay.Plate ADD PlateSet INT;
+GO
+
+UPDATE assay.Plate SET PlateSet = Rowid;
+ALTER TABLE assay.plate ALTER COLUMN PlateSet INT NOT NULL;
+ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateSet FOREIGN KEY (PlateSet) REFERENCES assay.PlateSet (RowId);
+CREATE INDEX IX_Plate_PlateSet ON assay.Plate (PlateSet);
+
+CREATE TABLE assay.PlateType
+(
+ RowId INT IDENTITY(1,1),
+ Rows INT NOT NULL,
+ Columns INT NOT NULL,
+ Description NVARCHAR(300) NOT NULL,
+ Archived BIT NOT NULL DEFAULT 0,
+
+ CONSTRAINT PK_PlateType PRIMARY KEY (RowId),
+ CONSTRAINT UQ_PlateType_Rows_Cols UNIQUE (Rows, Columns)
+);
+
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (3, 4, '12 well (3x4)');
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (4, 6, '24 well (4x6)');
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well (6x8)');
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)');
+INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)');
+INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (32, 48, '1536 well (32x48)', 1);
+INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)', 1);
+
+-- Rename type column to assayType
+EXEC sp_rename 'assay.Plate.Type', 'AssayType', 'COLUMN';
+-- Add type as a FK to assay.PlateType
+ALTER TABLE assay.Plate ADD PlateType INT;
+GO
+ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateType FOREIGN KEY (PlateType) REFERENCES assay.PlateType (RowId);
+
+-- Add ID and description columns to Plate and PlateSet tables
+ALTER TABLE assay.Plate ADD PlateId NVARCHAR(200);
+ALTER TABLE assay.Plate ADD Description NVARCHAR(300);
+ALTER TABLE assay.PlateSet ADD PlateSetId NVARCHAR(200);
+ALTER TABLE assay.PlateSet ADD Description NVARCHAR(300);
+GO
+
+-- Most existing plate sets will have a generated name, but mutated ones will get fixed up by the java upgrade script
+UPDATE assay.PlateSet SET PlateSetId = Name;
+
+UPDATE assay.Plate
+SET PlateType =
+ CASE
+ WHEN (Rows = 3 AND Columns = 4) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 3 AND Columns = 4)
+ WHEN (Rows = 4 AND Columns = 6) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 4 AND Columns = 6)
+ WHEN (Rows = 6 AND Columns = 8) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 6 AND Columns = 8)
+ WHEN (Rows = 8 AND Columns = 12) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 8 AND Columns = 12)
+ WHEN (Rows = 16 AND Columns = 24) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 16 AND Columns = 24)
+ WHEN (Rows = 32 AND Columns = 48) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 32 AND Columns = 48)
+ ELSE (SELECT RowId FROM assay.PlateType WHERE Rows = 0 AND Columns = 0)
+ END
+WHERE PlateType IS NULL;
+
+ALTER TABLE assay.Plate ALTER COLUMN PlateType INT NOT NULL;
+ALTER TABLE assay.Plate DROP COLUMN Rows;
+ALTER TABLE assay.Plate DROP COLUMN Columns;
+
+-- finalize plate and plateSet ID columns
+ALTER TABLE assay.Plate ALTER COLUMN PlateId NVARCHAR(200) NOT NULL;
+ALTER TABLE assay.Plate ADD CONSTRAINT UQ_Plate_PlateId UNIQUE (PlateId);
+
+ALTER TABLE assay.PlateSet ALTER COLUMN PlateSetId NVARCHAR(200) NOT NULL;
+ALTER TABLE assay.PlateSet ADD CONSTRAINT UQ_PlateSet_PlateSetId UNIQUE (PlateSetId);
+
+ALTER TABLE assay.PlateSet ADD Type NVARCHAR(64);
+ALTER TABLE assay.PlateSet ADD RootPlateSetId INT;
+ALTER TABLE assay.PlateSet ADD PrimaryPlateSetId INT;
+GO
+
+ALTER TABLE assay.PlateSet ADD CONSTRAINT FK_PlateSet_RootPlateSetId FOREIGN KEY (RootPlateSetId) REFERENCES assay.PlateSet (RowId);
+ALTER TABLE assay.PlateSet ADD CONSTRAINT FK_PlateSet_PrimaryPlateSetId FOREIGN KEY (PrimaryPlateSetId) REFERENCES assay.PlateSet (RowId);
+
+-- Update all pre-existing plate sets to type "assay"
+UPDATE assay.PlateSet SET type = 'assay';
+
+ALTER TABLE assay.PlateSet ALTER COLUMN Type NVARCHAR(64) NOT NULL;
+
+CREATE TABLE assay.PlateSetEdge
+(
+ FromPlateSetId INT NOT NULL,
+ ToPlateSetId INT NOT NULL,
+ RootPlateSetId INT NOT NULL,
+
+ CONSTRAINT FK_PlateSet_FromPlate FOREIGN KEY (FromPlateSetId) REFERENCES assay.PlateSet (RowId),
+ CONSTRAINT FK_PlateSet_ToPlate FOREIGN KEY (ToPlateSetId) REFERENCES assay.PlateSet (RowId),
+ CONSTRAINT FK_PlateSet_RootPlate FOREIGN KEY (RootPlateSetId) REFERENCES assay.PlateSet (RowId),
+ CONSTRAINT UQ_PlateSetEdge_FromPlate_ToPlate UNIQUE (FromPlateSetId, ToPlateSetId)
+);
+
+CREATE INDEX IX_PlateSetEdge_FromPlateSetId ON assay.PlateSetEdge (FromPlateSetId);
+CREATE INDEX IX_PlateSetEdge_ToPlateSetId ON assay.PlateSetEdge (ToPlateSetId);
+CREATE INDEX IX_PlateSetEdge_RootPlateSetId ON assay.PlateSetEdge (RootPlateSetId);
+
+CREATE TABLE assay.Hit
+(
+ RowId INT IDENTITY(1,1),
+ Container ENTITYID NOT NULL,
+ ProtocolId INT NOT NULL,
+ ResultId INT NOT NULL,
+ RunId INT NOT NULL,
+ WellLsid NVARCHAR(200) NOT NULL,
+
+ CONSTRAINT PK_Hit PRIMARY KEY (RowId),
+ CONSTRAINT FK_Hit_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId),
+ CONSTRAINT FK_Protocol_ProtocolId FOREIGN KEY (ProtocolId) REFERENCES exp.Protocol (RowId),
+ CONSTRAINT FK_Run_RunId FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId),
+ CONSTRAINT FK_Well_WellLsid FOREIGN KEY (WellLsid) REFERENCES assay.Well (Lsid),
+ CONSTRAINT UQ_Hit_RunId_ResultId UNIQUE (RunId, ResultId)
+);
+
+ALTER TABLE assay.Hit ADD PlateSetPath NVARCHAR (4000);
+GO
+
+ALTER TABLE assay.Hit ALTER COLUMN PlateSetPath NVARCHAR (4000) NOT NULL;
+GO
+
+ALTER TABLE assay.PlateSet ADD Template BIT NOT NULL DEFAULT 0;
+UPDATE assay.Plate SET Template = 0 WHERE Template = 1;
+
+ALTER TABLE assay.Plate ADD Archived BIT NOT NULL DEFAULT 0;
+
+UPDATE assay.Plate SET AssayType = 'Standard' WHERE AssayType IS NULL;
+ALTER TABLE assay.Plate ALTER COLUMN AssayType NVARCHAR(200) NOT NULL;
+
+-- Add index on assay.Well.SampleId to improve performance of DELETE operation on exp.Material table.
+CREATE INDEX IX_Well_SampleId ON assay.Well (SampleId);
+
+-- Add index on assay.WellGroupPositions.WellId to improve performance of DELETE operation on assay.Well table.
+CREATE INDEX IX_WellGroupPositions_WellId ON assay.WellGroupPositions (WellId);
+
+ALTER TABLE assay.plate ADD Barcode NVARCHAR(255);
+GO
+CREATE UNIQUE NONCLUSTERED INDEX UQ_Barcode ON assay.plate(Barcode) WHERE Barcode IS NOT NULL;
+GO
+
+UPDATE assay.plate
+SET Barcode = RIGHT(REPLICATE('0', 9) + CAST(rowid AS VARCHAR(9)), 9)
+WHERE Barcode IS NULL AND template = 0;
+
+ALTER TABLE assay.plate ADD CONSTRAINT check_template_true_barcode_null CHECK ((template = 0) OR Barcode IS NULL);
+
+-- Specify plate metadata columns on the plate set rather than the individual plates
+CREATE TABLE assay.PlateSetProperty
+(
+ RowId INT IDENTITY(1,1),
+ PlateSetId INT NOT NULL,
+ PropertyId INT NOT NULL,
+ PropertyURI NVARCHAR(300) NOT NULL,
+
+ CONSTRAINT PK_PlateSetProperty PRIMARY KEY (RowId),
+ CONSTRAINT UQ_PlateSetProperty_PlateSetId_PropertyId UNIQUE (PlateSetId, PropertyId),
+ CONSTRAINT FK_PlateSetProperty_PlateSetId FOREIGN KEY (PlateSetId) REFERENCES assay.PlateSet(RowId) ON DELETE CASCADE,
+ CONSTRAINT FK_PlateSetProperty_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor(PropertyId) ON DELETE CASCADE
+);
+
+INSERT INTO assay.PlateSetProperty (PlateSetId, PropertyId, PropertyURI)
+SELECT
+ PL.PlateSet AS PlateSetId,
+ PP.PropertyId,
+ PP.PropertyURI
+FROM assay.PlateProperty AS PP
+INNER JOIN assay.Plate AS PL ON PP.PlateId = PL.RowId
+GROUP BY PL.PlateSet, PP.PropertyId, PP.PropertyURI
+ORDER BY PlateSetId, PropertyId;
+
+DROP TABLE assay.PlateProperty;
+GO
+
+ALTER TABLE assay.platesetproperty
+ ADD FieldKey NVARCHAR(255);
+GO
+
+ALTER TABLE assay.platesetproperty
+ ADD CONSTRAINT either_identifier
+ CHECK (PropertyURI IS NOT NULL OR FieldKey IS NOT NULL);
+
+ALTER TABLE assay.platesetproperty ALTER COLUMN PropertyURI NVARCHAR(300) NULL;
+ALTER TABLE assay.platesetproperty ALTER COLUMN PropertyId INT NULL;
+
+ALTER TABLE assay.platesetproperty DROP CONSTRAINT UQ_PlateSetProperty_PlateSetId_PropertyId;
+CREATE UNIQUE INDEX UQ_PlateSetProperty_PlateSetId_PropertyId ON assay.platesetproperty (PlateSetId, PropertyId) WHERE PropertyId IS NOT NULL;
+
+ALTER TABLE assay.plateset ADD LSID LSIDtype;
+GO
+
+ALTER TABLE assay.plateset ALTER COLUMN LSID LSIDType NOT NULL;
+GO
+
+CREATE TABLE assay.FilterCriteria
+(
+ RowId INT IDENTITY(1,1),
+ PropertyId INT NOT NULL,
+ ReferencePropertyId INT NOT NULL,
+ DomainId INT NOT NULL,
+ Operation NVARCHAR(50) NOT NULL,
+ Value NVARCHAR(4000) NULL,
+
+ CONSTRAINT PK_FilterCriteria PRIMARY KEY (RowId),
+ CONSTRAINT FK_FilterCriteria_DomainDescriptor FOREIGN KEY (DomainId) REFERENCES exp.DomainDescriptor (DomainId) ON DELETE CASCADE,
+
+ -- SQL Server does not allow for multiple foreign keys to the same table to utilize ON DELETE CASCADE as it may
+ -- cause cycles or multiple cascade paths. The solution is to only ON DELETE CASCADE for one foreign key and
+ -- clean up upon delete of the property for other changes. See AssayResultDomainKind.deletePropertyDescriptor().
+ CONSTRAINT FK_FilterCriteria_PropertyDescriptor FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) ON DELETE CASCADE,
+ CONSTRAINT FK_FilterCriteria_PropertyDescriptor_Reference FOREIGN KEY (ReferencePropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) ON DELETE NO ACTION
+);
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.000-24.001.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.000-24.001.sql
deleted file mode 100644
index d04bc890411..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.000-24.001.sql
+++ /dev/null
@@ -1,30 +0,0 @@
-CREATE TABLE assay.PlateSet
-(
- RowId INT NOT NULL,
- Name NVARCHAR(200) NOT NULL,
- Container ENTITYID NOT NULL,
- Created DATETIME NOT NULL,
- CreatedBy USERID NOT NULL,
- Modified DATETIME NOT NULL,
- ModifiedBy USERID NOT NULL,
- Archived BIT NOT NULL DEFAULT 0,
-
- CONSTRAINT PK_PlateSet PRIMARY KEY (RowId)
-);
-
--- Insert a row into the plate set table for every plate in the system, store the plate row ID in the plate set table
--- in order to create the FK from the plate to plate set table
-INSERT INTO assay.PlateSet (RowId, Name, Container, Created, CreatedBy, Modified, ModifiedBy)
-SELECT RowId, 'TempPlateSet', Container, getdate(), CreatedBy, getdate(), ModifiedBy FROM assay.Plate;
-
--- Add the plate set field to the plate table and populate it with the plate set row ID
-ALTER TABLE assay.Plate ADD PlateSet INT;
-GO
-
-UPDATE assay.Plate SET PlateSet = Rowid;
-ALTER TABLE assay.plate ALTER COLUMN PlateSet INT NOT NULL;
-ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateSet FOREIGN KEY (PlateSet) REFERENCES assay.PlateSet (RowId);
-CREATE INDEX IX_Plate_PlateSet ON assay.Plate (PlateSet);
-
--- Run the java upgrade script to update plate set and plate tables to create the name expression based name values
-EXEC core.executeJavaUpgradeCode 'updatePlateSetNames';
\ No newline at end of file
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql
deleted file mode 100644
index 7bc1ade63be..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.001-24.002.sql
+++ /dev/null
@@ -1,63 +0,0 @@
-CREATE TABLE assay.PlateType
-(
- RowId INT IDENTITY(1,1),
- Rows INT NOT NULL,
- Columns INT NOT NULL,
- Description NVARCHAR(300) NOT NULL,
- Archived BIT NOT NULL DEFAULT 0,
-
- CONSTRAINT PK_PlateType PRIMARY KEY (RowId),
- CONSTRAINT UQ_PlateType_Rows_Cols UNIQUE (Rows, Columns)
-);
-
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (3, 4, '12 well (3x4)');
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (4, 6, '24 well (4x6)');
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (6, 8, '48 well (6x8)');
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (8, 12, '96 well (8x12)');
-INSERT INTO assay.PlateType (Rows, Columns, Description) VALUES (16, 24, '384 well (16x24)');
-INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (32, 48, '1536 well (32x48)', 1);
-INSERT INTO assay.PlateType (Rows, Columns, Description, Archived) VALUES (0, 0, 'Invalid Plate Type (Plates which were created with non-valid row & column combinations)', 1);
-
--- Rename type column to assayType
-EXEC sp_rename 'assay.Plate.Type', 'AssayType', 'COLUMN';
--- Add type as a FK to assay.PlateType
-ALTER TABLE assay.Plate ADD PlateType INT;
-GO
-ALTER TABLE assay.Plate ADD CONSTRAINT FK_Plate_PlateType FOREIGN KEY (PlateType) REFERENCES assay.PlateType (RowId);
-
--- Add ID and description columns to Plate and PlateSet tables
-ALTER TABLE assay.Plate ADD PlateId NVARCHAR(200);
-ALTER TABLE assay.Plate ADD Description NVARCHAR(300);
-ALTER TABLE assay.PlateSet ADD PlateSetId NVARCHAR(200);
-ALTER TABLE assay.PlateSet ADD Description NVARCHAR(300);
-GO
-
--- Most existing plate sets will have a generated name, but mutated ones will get fixed up by the java upgrade script
-UPDATE assay.PlateSet SET PlateSetId = Name;
-
-UPDATE assay.Plate
-SET PlateType =
- CASE
- WHEN (Rows = 3 AND Columns = 4) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 3 AND Columns = 4)
- WHEN (Rows = 4 AND Columns = 6) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 4 AND Columns = 6)
- WHEN (Rows = 6 AND Columns = 8) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 6 AND Columns = 8)
- WHEN (Rows = 8 AND Columns = 12) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 8 AND Columns = 12)
- WHEN (Rows = 16 AND Columns = 24) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 16 AND Columns = 24)
- WHEN (Rows = 32 AND Columns = 48) THEN (SELECT RowId FROM assay.PlateType WHERE Rows = 32 AND Columns = 48)
- ELSE (SELECT RowId FROM assay.PlateType WHERE Rows = 0 AND Columns = 0)
- END
-WHERE PlateType IS NULL;
-
-ALTER TABLE assay.Plate ALTER COLUMN PlateType INT NOT NULL;
-ALTER TABLE assay.Plate DROP COLUMN Rows;
-ALTER TABLE assay.Plate DROP COLUMN Columns;
-
--- upgrade script to set the plate ID value in assay.Plate
-EXEC core.executeJavaUpgradeCode 'initializePlateAndPlateSetIDs';
-
--- finalize plate and plateSet ID columns
-ALTER TABLE assay.Plate ALTER COLUMN PlateId NVARCHAR(200) NOT NULL;
-ALTER TABLE assay.Plate ADD CONSTRAINT UQ_Plate_PlateId UNIQUE (PlateId);
-
-ALTER TABLE assay.PlateSet ALTER COLUMN PlateSetId NVARCHAR(200) NOT NULL;
-ALTER TABLE assay.PlateSet ADD CONSTRAINT UQ_PlateSet_PlateSetId UNIQUE (PlateSetId);
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.002-24.003.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.002-24.003.sql
deleted file mode 100644
index 231e36fdea4..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.002-24.003.sql
+++ /dev/null
@@ -1,6 +0,0 @@
--- Provisioned schema used by PlateMetadataDomainKind
-CREATE SCHEMA assaywell;
-GO
-
--- upgrade script to set the plate ID value in assay.Plate
-EXEC core.executeJavaUpgradeCode 'deletePlateVocabDomains';
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.003-24.004.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.003-24.004.sql
deleted file mode 100644
index 3da4dbaa6c8..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.003-24.004.sql
+++ /dev/null
@@ -1,28 +0,0 @@
-ALTER TABLE assay.PlateSet ADD Type NVARCHAR(64);
-ALTER TABLE assay.PlateSet ADD RootPlateSetId INT;
-ALTER TABLE assay.PlateSet ADD PrimaryPlateSetId INT;
-GO
-
-ALTER TABLE assay.PlateSet ADD CONSTRAINT FK_PlateSet_RootPlateSetId FOREIGN KEY (RootPlateSetId) REFERENCES assay.PlateSet (RowId);
-ALTER TABLE assay.PlateSet ADD CONSTRAINT FK_PlateSet_PrimaryPlateSetId FOREIGN KEY (PrimaryPlateSetId) REFERENCES assay.PlateSet (RowId);
-
--- Update all pre-existing plate sets to type "assay"
-UPDATE assay.PlateSet SET type = 'assay';
-
-ALTER TABLE assay.PlateSet ALTER COLUMN Type NVARCHAR(64) NOT NULL;
-
-CREATE TABLE assay.PlateSetEdge
-(
- FromPlateSetId INT NOT NULL,
- ToPlateSetId INT NOT NULL,
- RootPlateSetId INT NOT NULL,
-
- CONSTRAINT FK_PlateSet_FromPlate FOREIGN KEY (FromPlateSetId) REFERENCES assay.PlateSet (RowId),
- CONSTRAINT FK_PlateSet_ToPlate FOREIGN KEY (ToPlateSetId) REFERENCES assay.PlateSet (RowId),
- CONSTRAINT FK_PlateSet_RootPlate FOREIGN KEY (RootPlateSetId) REFERENCES assay.PlateSet (RowId),
- CONSTRAINT UQ_PlateSetEdge_FromPlate_ToPlate UNIQUE (FromPlateSetId, ToPlateSetId)
-);
-
-CREATE INDEX IX_PlateSetEdge_FromPlateSetId ON assay.PlateSetEdge (FromPlateSetId);
-CREATE INDEX IX_PlateSetEdge_ToPlateSetId ON assay.PlateSetEdge (ToPlateSetId);
-CREATE INDEX IX_PlateSetEdge_RootPlateSetId ON assay.PlateSetEdge (RootPlateSetId);
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.004-24.005.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.004-24.005.sql
deleted file mode 100644
index f6ffbe21df1..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.004-24.005.sql
+++ /dev/null
@@ -1,16 +0,0 @@
-CREATE TABLE assay.Hit
-(
- RowId INT IDENTITY(1,1),
- Container ENTITYID NOT NULL,
- ProtocolId INT NOT NULL,
- ResultId INT NOT NULL,
- RunId INT NOT NULL,
- WellLsid NVARCHAR(200) NOT NULL,
-
- CONSTRAINT PK_Hit PRIMARY KEY (RowId),
- CONSTRAINT FK_Hit_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId),
- CONSTRAINT FK_Protocol_ProtocolId FOREIGN KEY (ProtocolId) REFERENCES exp.Protocol (RowId),
- CONSTRAINT FK_Run_RunId FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId),
- CONSTRAINT FK_Well_WellLsid FOREIGN KEY (WellLsid) REFERENCES assay.Well (Lsid),
- CONSTRAINT UQ_Hit_RunId_ResultId UNIQUE (RunId, ResultId)
-);
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.005-24.006.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.005-24.006.sql
deleted file mode 100644
index 60b4c333a35..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.005-24.006.sql
+++ /dev/null
@@ -1,8 +0,0 @@
-ALTER TABLE assay.Hit ADD PlateSetPath NVARCHAR (4000);
-GO
-
--- Populate paths of pre-existing hits
-EXEC core.executeJavaUpgradeCode 'populatePlateSetPaths';
-
-ALTER TABLE assay.Hit ALTER COLUMN PlateSetPath NVARCHAR (4000) NOT NULL;
-GO
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.006-24.007.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.006-24.007.sql
deleted file mode 100644
index 0e2d1c99d14..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.006-24.007.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-ALTER TABLE assay.PlateSet ADD Template BIT NOT NULL DEFAULT 0;
-UPDATE assay.Plate SET Template = 0 WHERE Template = 1;
-
-ALTER TABLE assay.Plate ADD Archived BIT NOT NULL DEFAULT 0;
-
-UPDATE assay.Plate SET AssayType = 'Standard' WHERE AssayType IS NULL;
-ALTER TABLE assay.Plate ALTER COLUMN AssayType NVARCHAR(200) NOT NULL;
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.007-24.008.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.007-24.008.sql
deleted file mode 100644
index 20ca47b7647..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.007-24.008.sql
+++ /dev/null
@@ -1,2 +0,0 @@
--- Biologics is not supported on SQL Server so this upgrade is not applicable
--- EXEC core.executeJavaUpgradeCode 'populatePlateWellTypes';
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.008-24.009.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.008-24.009.sql
deleted file mode 100644
index 60acb08af3b..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.008-24.009.sql
+++ /dev/null
@@ -1,5 +0,0 @@
--- Add index on assay.Well.SampleId to improve performance of DELETE operation on exp.Material table.
-CREATE INDEX IX_Well_SampleId ON assay.Well (SampleId);
-
--- Add index on assay.WellGroupPositions.WellId to improve performance of DELETE operation on assay.Well table.
-CREATE INDEX IX_WellGroupPositions_WellId ON assay.WellGroupPositions (WellId);
\ No newline at end of file
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.009-24.010.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.009-24.010.sql
deleted file mode 100644
index b47165c52d3..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.009-24.010.sql
+++ /dev/null
@@ -1 +0,0 @@
-EXEC core.executeJavaUpgradeCode 'renameWellMetadataFields';
\ No newline at end of file
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.010-24.011.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.010-24.011.sql
deleted file mode 100644
index 7a5697da5a7..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.010-24.011.sql
+++ /dev/null
@@ -1,12 +0,0 @@
-ALTER TABLE assay.plate ADD Barcode NVARCHAR(255);
-GO
-CREATE UNIQUE NONCLUSTERED INDEX UQ_Barcode ON assay.plate(Barcode) WHERE Barcode IS NOT NULL;
-GO
-
-UPDATE assay.plate
-SET Barcode = RIGHT(REPLICATE('0', 9) + CAST(rowid AS VARCHAR(9)), 9)
-WHERE Barcode IS NULL AND template = 0;
-
-ALTER TABLE assay.plate ADD CONSTRAINT check_template_true_barcode_null CHECK ((template = 0) OR Barcode IS NULL);
-
-EXEC core.executeJavaUpgradeCode 'updateBarcodeSequence';
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.011-24.012.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.011-24.012.sql
deleted file mode 100644
index 3e5313f81cb..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.011-24.012.sql
+++ /dev/null
@@ -1,26 +0,0 @@
--- Specify plate metadata columns on the plate set rather than the individual plates
-CREATE TABLE assay.PlateSetProperty
-(
- RowId INT IDENTITY(1,1),
- PlateSetId INT NOT NULL,
- PropertyId INT NOT NULL,
- PropertyURI NVARCHAR(300) NOT NULL,
-
- CONSTRAINT PK_PlateSetProperty PRIMARY KEY (RowId),
- CONSTRAINT UQ_PlateSetProperty_PlateSetId_PropertyId UNIQUE (PlateSetId, PropertyId),
- CONSTRAINT FK_PlateSetProperty_PlateSetId FOREIGN KEY (PlateSetId) REFERENCES assay.PlateSet(RowId) ON DELETE CASCADE,
- CONSTRAINT FK_PlateSetProperty_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor(PropertyId) ON DELETE CASCADE
-);
-
-INSERT INTO assay.PlateSetProperty (PlateSetId, PropertyId, PropertyURI)
-SELECT
- PL.PlateSet AS PlateSetId,
- PP.PropertyId,
- PP.PropertyURI
-FROM assay.PlateProperty AS PP
-INNER JOIN assay.Plate AS PL ON PP.PlateId = PL.RowId
-GROUP BY PL.PlateSet, PP.PropertyId, PP.PropertyURI
-ORDER BY PlateSetId, PropertyId;
-
-DROP TABLE assay.PlateProperty;
-GO
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.012-24.013.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.012-24.013.sql
deleted file mode 100644
index 92c302a6854..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.012-24.013.sql
+++ /dev/null
@@ -1,15 +0,0 @@
-ALTER TABLE assay.platesetproperty
- ADD FieldKey NVARCHAR(255);
-GO
-
-ALTER TABLE assay.platesetproperty
- ADD CONSTRAINT either_identifier
- CHECK (PropertyURI IS NOT NULL OR FieldKey IS NOT NULL);
-
-ALTER TABLE assay.platesetproperty ALTER COLUMN PropertyURI NVARCHAR(300) NULL;
-ALTER TABLE assay.platesetproperty ALTER COLUMN PropertyId INT NULL;
-
-ALTER TABLE assay.platesetproperty DROP CONSTRAINT UQ_PlateSetProperty_PlateSetId_PropertyId;
-CREATE UNIQUE INDEX UQ_PlateSetProperty_PlateSetId_PropertyId ON assay.platesetproperty (PlateSetId, PropertyId) WHERE PropertyId IS NOT NULL;
-
-EXEC core.executeJavaUpgradeCode 'updateBuiltInColumns';
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.013-24.014.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.013-24.014.sql
deleted file mode 100644
index eac638dab7c..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.013-24.014.sql
+++ /dev/null
@@ -1 +0,0 @@
-EXEC core.executeJavaUpgradeCode 'initializeWellExclusions';
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.014-24.015.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.014-24.015.sql
deleted file mode 100644
index 93e0e23dba3..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.014-24.015.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-ALTER TABLE assay.plateset ADD LSID LSIDtype;
-GO
-
-EXEC core.executeJavaUpgradeCode 'addLsidToPlateSets';
-
-ALTER TABLE assay.plateset ALTER COLUMN LSID LSIDType NOT NULL;
-GO
diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-24.015-24.016.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-24.015-24.016.sql
deleted file mode 100644
index 38564102d01..00000000000
--- a/assay/resources/schemas/dbscripts/sqlserver/assay-24.015-24.016.sql
+++ /dev/null
@@ -1,20 +0,0 @@
-CREATE TABLE assay.FilterCriteria
-(
- RowId INT IDENTITY(1,1),
- PropertyId INT NOT NULL,
- ReferencePropertyId INT NOT NULL,
- DomainId INT NOT NULL,
- Operation NVARCHAR(50) NOT NULL,
- Value NVARCHAR(4000) NULL,
-
- CONSTRAINT PK_FilterCriteria PRIMARY KEY (RowId),
- CONSTRAINT FK_FilterCriteria_DomainDescriptor FOREIGN KEY (DomainId) REFERENCES exp.DomainDescriptor (DomainId) ON DELETE CASCADE,
-
- -- SQL Server does not allow for multiple foreign keys to the same table to utilize ON DELETE CASCADE as it may
- -- cause cycles or multiple cascade paths. The solution is to only ON DELETE CASCADE for one foreign key and
- -- clean up upon delete of the property for other changes. See AssayResultDomainKind.deletePropertyDescriptor().
- CONSTRAINT FK_FilterCriteria_PropertyDescriptor FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) ON DELETE CASCADE,
- CONSTRAINT FK_FilterCriteria_PropertyDescriptor_Reference FOREIGN KEY (ReferencePropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) ON DELETE NO ACTION
-);
-
-EXEC core.executeJavaUpgradeCode 'initializeHitSelectionCriteria';
diff --git a/assay/src/org/labkey/assay/AssayUpgradeCode.java b/assay/src/org/labkey/assay/AssayUpgradeCode.java
index 6a28e01042e..317f904b206 100644
--- a/assay/src/org/labkey/assay/AssayUpgradeCode.java
+++ b/assay/src/org/labkey/assay/AssayUpgradeCode.java
@@ -1,822 +1,31 @@
package org.labkey.assay;
-import org.apache.commons.collections4.MapUtils;
-import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
-import org.jetbrains.annotations.Nullable;
-import org.labkey.api.assay.AssayProvider;
-import org.labkey.api.assay.AssayResultDomainKind;
-import org.labkey.api.assay.AssayService;
-import org.labkey.api.assay.plate.PlateDataStateManager;
-import org.labkey.api.assay.plate.PlateService;
-import org.labkey.api.assay.plate.PlateSet;
-import org.labkey.api.assay.plate.Position;
import org.labkey.api.assay.plate.WellGroup;
-import org.labkey.api.collections.CaseInsensitiveHashMap;
-import org.labkey.api.collections.CaseInsensitiveHashSet;
-import org.labkey.api.collections.IntHashMap;
-import org.labkey.api.collections.LongHashMap;
import org.labkey.api.data.Container;
-import org.labkey.api.data.ContainerFilter;
import org.labkey.api.data.ContainerManager;
-import org.labkey.api.data.CoreSchema;
-import org.labkey.api.data.DbSchema;
import org.labkey.api.data.DbScope;
-import org.labkey.api.data.DbSequence;
-import org.labkey.api.data.DbSequenceManager;
-import org.labkey.api.data.DeferredUpgrade;
-import org.labkey.api.data.JdbcType;
-import org.labkey.api.data.NameGenerator;
-import org.labkey.api.data.NameGeneratorState;
-import org.labkey.api.data.PropertyStorageSpec;
-import org.labkey.api.data.Results;
import org.labkey.api.data.SQLFragment;
import org.labkey.api.data.SqlExecutor;
import org.labkey.api.data.SqlSelector;
import org.labkey.api.data.Table;
-import org.labkey.api.data.TableInfo;
-import org.labkey.api.data.TableSelector;
import org.labkey.api.data.UpgradeCode;
import org.labkey.api.exp.Lsid;
-import org.labkey.api.exp.OntologyManager;
-import org.labkey.api.exp.api.ExpProtocol;
-import org.labkey.api.exp.property.Domain;
-import org.labkey.api.exp.property.DomainKind;
-import org.labkey.api.exp.property.DomainProperty;
-import org.labkey.api.exp.property.Lookup;
-import org.labkey.api.exp.property.PropertyService;
import org.labkey.api.module.ModuleContext;
-import org.labkey.api.query.SchemaKey;
-import org.labkey.api.query.ValidationException;
-import org.labkey.api.security.User;
-import org.labkey.api.util.Pair;
-import org.labkey.assay.plate.PlateImpl;
import org.labkey.assay.plate.PlateManager;
-import org.labkey.assay.plate.PlateMetadataDomainKind;
-import org.labkey.assay.plate.TsvPlateLayoutHandler;
-import org.labkey.assay.plate.model.PlateSetLineage;
-import org.labkey.assay.plate.query.PlateTable;
-import org.labkey.assay.plate.query.WellTable;
import org.labkey.assay.query.AssayDbSchema;
import java.sql.ResultSet;
-import java.sql.SQLException;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-
-import static org.labkey.api.assay.plate.AssayPlateMetadataService.HIT_SELECTION_CRITERIA_COLUMN_NAME;
-import static org.labkey.api.util.IntegerUtils.asInteger;
-import static org.labkey.assay.plate.PlateMetadataDomainKind.Column;
public class AssayUpgradeCode implements UpgradeCode
{
private static final Logger _log = LogManager.getLogger(AssayUpgradeCode.class);
- /**
- * Called from assay-24.000-24.001.sql
- *
- * The referenced upgrade script creates a new plate set for every plate in the system. We now
- * want to iterate over each plate set to set the name using the configured name expression.
- */
- @SuppressWarnings({"UnusedDeclaration"})
- public static void updatePlateSetNames(ModuleContext ctx) throws Exception
- {
- if (ctx.isNewInstall())
- return;
-
- DbScope scope = AssayDbSchema.getInstance().getSchema().getScope();
- try (DbScope.Transaction tx = scope.ensureTransaction())
- {
- TableInfo plateSetTable = AssayDbSchema.getInstance().getTableInfoPlateSet();
-
- // Set the DbSequence minimum
- {
- SQLFragment sql = new SQLFragment("SELECT MAX(rowId) FROM ").append(plateSetTable, "");
- Integer maxRowId = new SqlSelector(AssayDbSchema.getInstance().getSchema(), sql).getObject(Integer.class);
-
- if (maxRowId != null)
- {
- DbSequence sequence = DbSequenceManager.get(ContainerManager.getRoot(), plateSetTable.getDbSequenceName("RowId"));
- sequence.ensureMinimum(maxRowId);
- }
- }
-
- _log.info("Start updating temporary plate set names with the configured name expression");
- List plateSetRowIds = new TableSelector(plateSetTable, Collections.singleton("RowId")).getArrayList(Integer.class);
-
- // This is a copy of PlateManager.PLATE_SET_NAME_EXPRESSION as set when this script was written.
- // Copied here to allow this script to assume that only the Plate Set "RowId" value is needed for the
- // generated name.
- String PLATE_SET_NAME_EXPRESSION = "PLS-${now:date('yyyyMMdd')}-${RowId}";
- NameGenerator nameGenerator = new NameGenerator(PLATE_SET_NAME_EXPRESSION, plateSetTable, false, null, null, null);
- NameGeneratorState state = nameGenerator.createState(false);
-
- for (Integer plateSetRowId : plateSetRowIds)
- {
- String name = nameGenerator.generateName(state, CaseInsensitiveHashMap.of("RowId", plateSetRowId));
- state.cleanUp();
-
- SQLFragment sql = new SQLFragment("UPDATE ").append(plateSetTable, "")
- .append(" SET Name = ?")
- .add(name)
- .append(" WHERE RowId = ?")
- .add(plateSetRowId);
-
- new SqlExecutor(AssayDbSchema.getInstance().getSchema()).execute(sql);
- }
-
- _log.info("Successfully updated " + plateSetRowIds.size() + " plate set names");
- tx.commit();
- }
- }
-
- /**
- * Called from assay-24.001-24.002.sql
- *
- * Iterate over each plate and plate set to generate a Plate ID and PlateSet ID based on the
- * configured name expression for each.
- */
- @SuppressWarnings({"UnusedDeclaration"})
- public static void initializePlateAndPlateSetIDs(ModuleContext ctx) throws Exception
- {
- if (ctx.isNewInstall())
- return;
-
- DbScope scope = AssayDbSchema.getInstance().getSchema().getScope();
- try (DbScope.Transaction tx = scope.ensureTransaction())
- {
- _log.info("Start initializing Plate IDs");
-
- try (Results rs = new TableSelector(AssayDbSchema.getInstance().getTableInfoPlate()).getResults())
- {
- int platesUpgraded = 0;
- while (rs.next())
- {
- Map row = rs.getRowMap();
- // get the plate container
- String containerId = String.valueOf(row.get("container"));
- Container c = ContainerManager.getForId(containerId);
- if (c != null)
- {
- row.put("name", null);
-
- NameGenerator nameGenerator = new NameGenerator(PlateManager.get().getPlateNameExpression(), AssayDbSchema.getInstance().getTableInfoPlate(), false, c, null, null);
- NameGeneratorState state = nameGenerator.createState(false);
- String name = nameGenerator.generateName(state, row);
- state.cleanUp();
-
- SQLFragment sql = new SQLFragment("UPDATE ").append(AssayDbSchema.getInstance().getTableInfoPlate(), "")
- .append(" SET PlateId = ?")
- .add(name)
- .append(" WHERE RowId = ?")
- .add(row.get("rowId"));
- new SqlExecutor(AssayDbSchema.getInstance().getSchema()).execute(sql);
- platesUpgraded++;
- }
- else
- _log.error("Container for Plate ID : " + row.get("rowId") + " could not be resolved.");
- }
- _log.info("Successfully updated " + platesUpgraded + " plate IDs");
- }
-
- _log.info("Start initializing PlateSet IDs");
- try (Results rs = new TableSelector(AssayDbSchema.getInstance().getTableInfoPlateSet()).getResults())
- {
- NameGenerator nameGenerator = new NameGenerator(PlateManager.get().getPlateSetNameExpression(), AssayDbSchema.getInstance().getTableInfoPlateSet(), false, null, null, null);
- NameGeneratorState state = nameGenerator.createState(false);
- int plateSetsUpgraded = 0;
- while (rs.next())
- {
- Map row = rs.getRowMap();
- // for plate sets, they should have a valid PlateSetId, but if the name was not generated (or mutated), regenerate a new
- // plate set id
- if (!String.valueOf(row.get("name")).startsWith("PLS-"))
- {
- row.put("name", null);
- String name = nameGenerator.generateName(state, row);
- state.cleanUp();
-
- SQLFragment sql = new SQLFragment("UPDATE ").append(AssayDbSchema.getInstance().getTableInfoPlateSet(), "")
- .append(" SET PlateSetId = ?")
- .add(name)
- .append(" WHERE RowId = ?")
- .add(row.get("rowId"));
- new SqlExecutor(AssayDbSchema.getInstance().getSchema()).execute(sql);
- plateSetsUpgraded++;
- }
- }
- _log.info("Successfully updated " + plateSetsUpgraded + " plate set IDs");
- }
- tx.commit();
- }
- }
-
- /**
- * Well metadata has transitioned to a provisioned architecture.
- */
- private static @Nullable Domain getPlateMetadataVocabDomain(Container container, User user)
- {
- DomainKind> vocabDomainKind = PropertyService.get().getDomainKindByName("Vocabulary");
-
- if (vocabDomainKind == null)
- return null;
-
- // the domain is scoped at the project level (project and subfolder scoping)
- Container domainContainer = PlateManager.get().getPlateMetadataDomainContainer(container);
- String domainURI = vocabDomainKind.generateDomainURI(null, "PlateMetadataDomain", domainContainer, user);
- return PropertyService.get().getDomain(container, domainURI);
- }
-
- /**
- * Called from assay-24.002-24.003.sql to delete the vocabulary domains associated with
- * plate metadata. This upgrade transitions to using a provisioned table approach. Since the plate features are
- * still under an experimental flag we won't worry about upgrading the domains.
- */
- @SuppressWarnings({"UnusedDeclaration"})
- public static void deletePlateVocabDomains(ModuleContext ctx) throws Exception
- {
- if (ctx.isNewInstall())
- return;
-
- DbScope scope = AssayDbSchema.getInstance().getSchema().getScope();
- try (DbScope.Transaction tx = scope.ensureTransaction())
- {
- // just truncate the plate to custom property mappings
- Table.truncate(AssayDbSchema.getInstance().getSchema().getTable("PlateProperty"));
- List biologicsFolders = new ArrayList<>();
-
- for (Container container : ContainerManager.getAllChildren(ContainerManager.getRoot()))
- {
- if (container != null)
- {
- Domain domain = getPlateMetadataVocabDomain(container, User.getAdminServiceUser());
- if (domain != null)
- {
- // delete the plate metadata values
- SQLFragment sql = new SQLFragment("SELECT Lsid FROM ")
- .append(AssayDbSchema.getInstance().getTableInfoWell(), "")
- .append(" WHERE Container = ?")
- .add(container);
- OntologyManager.deleteOntologyObjects(AssayDbSchema.getInstance().getSchema(), sql, container);
-
- // delete the domain
- domain.delete(User.getAdminServiceUser());
- }
-
- if (isBiologicsFolder(container.getProject()))
- {
- // ensure the plate metadata domain for the top level biologics projects
- if (container.isProject())
- PlateManager.get().ensurePlateMetadataDomain(container, User.getAdminServiceUser(), false);
- biologicsFolders.add(container);
- }
- }
- }
-
- // for existing plates we also need to populate the new provisioned tables so that wells can be joined
- // to the metadata properly
- for (Container container : biologicsFolders)
- {
- TableInfo tinfo = PlateManager.get().getPlateMetadataTable(container, User.getAdminServiceUser());
- if (tinfo != null)
- {
- SQLFragment sql = new SQLFragment("INSERT INTO ").append(tinfo, "")
- .append(" (Lsid) SELECT Lsid FROM ").append(AssayDbSchema.getInstance().getTableInfoWell(), "")
- .append(" WHERE Container = ?").add(container);
-
- new SqlExecutor(AssayDbSchema.getInstance().getScope()).execute(sql);
- }
- }
- tx.commit();
- }
- }
-
- /**
- * Called from assay-24.005-24.006.sql
- * Populates
- */
- @SuppressWarnings({"UnusedDeclaration"})
- public static void populatePlateSetPaths(ModuleContext ctx) throws Exception
- {
- if (ctx.isNewInstall())
- return;
-
- DbScope scope = AssayDbSchema.getInstance().getSchema().getScope();
- try (DbScope.Transaction tx = scope.ensureTransaction())
- {
- Map plateSetPaths = new IntHashMap<>();
- Map> plateSetsToHits = new IntHashMap<>();
-
- SQLFragment sql = new SQLFragment("SELECT Hit.RowId AS HitRowId, PlateSet.RowId AS PlateSetRowId")
- .append(" FROM assay.PlateSet")
- .append(" INNER JOIN assay.Plate ON Plate.PlateSet = PlateSet.RowId")
- .append(" INNER JOIN assay.Well ON Well.PlateId = Plate.RowId")
- .append(" INNER JOIN assay.Hit ON Hit.WellLsid = Well.Lsid")
- .appendEOS();
- Collection