diff --git a/announcements/module.properties b/announcements/module.properties index 0c8fc6530fa..cd44314cb1b 100644 --- a/announcements/module.properties +++ b/announcements/module.properties @@ -13,5 +13,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/announcements/resources/schemas/dbscripts/sqlserver/comm-0.000-24.000.sql b/announcements/resources/schemas/dbscripts/sqlserver/comm-0.000-24.000.sql deleted file mode 100644 index c347b8472ab..00000000000 --- a/announcements/resources/schemas/dbscripts/sqlserver/comm-0.000-24.000.sql +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (c) 2017-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - --- Create schema comm: tables for Announcements and Wiki - -CREATE SCHEMA comm; -GO - -CREATE TABLE comm.Announcements -( - RowId INT IDENTITY(1,1) NOT NULL, - EntityId ENTITYID NOT NULL, - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - Parent ENTITYID, - Title NVARCHAR(255), - Expires DATETIME, - Body NTEXT, - RendererType NVARCHAR(50) NULL, -- Updates to properties will result in NULL body and NULL render type - Status VARCHAR(50) NULL, - AssignedTo USERID NULL, - DiscussionSrcIdentifier NVARCHAR(100) NULL, - DiscussionSrcURL NVARCHAR(1000) NULL, - LastIndexed DATETIME NULL, - Approved DATETIME NULL, - - CONSTRAINT PK_Announcements PRIMARY KEY (RowId), - CONSTRAINT UQ_Announcements UNIQUE CLUSTERED (Container, Parent, RowId) -); - -CREATE INDEX IX_DiscussionSrcIdentifier ON comm.announcements(Container, DiscussionSrcIdentifier); - -ALTER TABLE comm.Announcements ADD DiscussionSrcEntityType VARCHAR(100) NULL; - -CREATE TABLE comm.Pages -( - RowId INT IDENTITY(1,1) NOT NULL, - EntityId ENTITYID NOT NULL, - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Owner USERID, - Container ENTITYID NOT NULL, - Name NVARCHAR(255) NOT NULL, - Parent INT NOT NULL, - DisplayOrder FLOAT NOT NULL, - PageVersionId INT NULL, - ShowAttachments BIT NOT NULL DEFAULT 1, - LastIndexed DATETIME NULL, - ShouldIndex BIT DEFAULT 1, - - CONSTRAINT PK_Pages PRIMARY KEY (EntityId), - CONSTRAINT UQ_Pages UNIQUE CLUSTERED (Container, Name) -); - --- Add missing indices on comm.Pages -CREATE INDEX IDX_Pages_PageVersionId ON comm.Pages(PageVersionId); -CREATE INDEX IDX_Pages_Parent ON comm.Pages(Parent); -CREATE UNIQUE INDEX UQ_Pages_RowId ON comm.Pages(RowId); - --- Switch from -1 to NULL for no parent -ALTER TABLE comm.Pages ALTER COLUMN Parent INT NULL; - --- Add an FK -ALTER TABLE comm.Pages - ADD CONSTRAINT FK_Pages_Parent FOREIGN KEY (Parent) - REFERENCES comm.Pages (RowId); - -CREATE TABLE comm.PageVersions -( - RowId INT IDENTITY (1, 1) NOT NULL, - PageEntityId ENTITYID NOT NULL, - CreatedBy USERID NULL, - Created DATETIME NULL, - Owner USERID NULL, - Version INT NOT NULL, - Title NVARCHAR (255), - Body NTEXT, - RendererType NVARCHAR(50) NOT NULL DEFAULT 'RADEOX', - - CONSTRAINT PK_PageVersions PRIMARY KEY (RowId), - CONSTRAINT FK_PageVersions_Pages FOREIGN KEY (PageEntityId) REFERENCES comm.Pages(EntityId), - CONSTRAINT UQ_PageVersions UNIQUE (PageEntityId, Version) -); - -ALTER TABLE comm.Pages - ADD CONSTRAINT FK_Pages_PageVersions FOREIGN KEY (PageVersionId) REFERENCES comm.PageVersions (RowId); - --- Discussions can be private, constrained to a certain subset of users (like a Cc: line) -CREATE TABLE comm.UserList -( - MessageId INT NOT NULL, - UserId USERID NOT NULL, - - CONSTRAINT PK_UserList PRIMARY KEY (MessageId, UserId) -); - --- Improve performance of user list lookups for permission checking -CREATE INDEX IX_UserList_UserId ON comm.UserList(UserId); - -CREATE TABLE comm.RSSFeeds -( - RowId INT IDENTITY(1,1) NOT NULL, - EntityId ENTITYID NOT NULL, - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - FeedName NVARCHAR(250) NULL, - FeedURL NVARCHAR(1000) NOT NULL, - LastRead DATETIME NULL, - Content NVARCHAR(MAX), - - CONSTRAINT PK_RSSFeeds PRIMARY KEY (RowId), - CONSTRAINT UQ_RSSFeeds UNIQUE CLUSTERED (Container, RowId) -); - -CREATE TABLE comm.Tours -( - RowId INT IDENTITY(1,1) NOT NULL, - Title NVARCHAR(500) NOT NULL, - Description NVARCHAR(4000), - Container ENTITYID NOT NULL, - EntityId ENTITYID NOT NULL, - Created DATETIME, - CreatedBy USERID, - Modified DATETIME, - ModifiedBy USERID, - Json NVARCHAR(MAX), - Mode INT NOT NULL DEFAULT 0, - - CONSTRAINT PK_ToursId PRIMARY KEY (RowId) -); - -CREATE TABLE comm.PageAliases -( - Container ENTITYID NOT NULL, - Alias NVARCHAR(255) NOT NULL, - PageRowId INT NOT NULL, - - CONSTRAINT PK_PageAliases PRIMARY KEY (Container, Alias) -); - --- Switch from PK to UNIQUE INDEX to match PostgreSQL -ALTER TABLE comm.PageAliases DROP CONSTRAINT PK_PageAliases; -CREATE UNIQUE INDEX UQ_PageAliases ON comm.PageAliases (Container, Alias); diff --git a/announcements/resources/schemas/dbscripts/sqlserver/comm-25.000-25.001.sql b/announcements/resources/schemas/dbscripts/sqlserver/comm-25.000-25.001.sql deleted file mode 100644 index f0113e01480..00000000000 --- a/announcements/resources/schemas/dbscripts/sqlserver/comm-25.000-25.001.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -DROP TABLE comm.Tours; \ No newline at end of file diff --git a/announcements/resources/schemas/dbscripts/sqlserver/comm-25.001-25.002.sql b/announcements/resources/schemas/dbscripts/sqlserver/comm-25.001-25.002.sql deleted file mode 100644 index fc5f8b046d3..00000000000 --- a/announcements/resources/schemas/dbscripts/sqlserver/comm-25.001-25.002.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -DELETE FROM comm.UserList WHERE MessageId NOT IN (SELECT RowId FROM comm.Announcements); -ALTER TABLE comm.UserList ADD CONSTRAINT FK_UserList_Announcements FOREIGN KEY (MessageId) REFERENCES comm.Announcements (RowId); diff --git a/announcements/resources/schemas/dbscripts/sqlserver/comm-25.002-25.003.sql b/announcements/resources/schemas/dbscripts/sqlserver/comm-25.002-25.003.sql deleted file mode 100644 index fcc3ab2cd6b..00000000000 --- a/announcements/resources/schemas/dbscripts/sqlserver/comm-25.002-25.003.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -ALTER TABLE comm.Announcements DROP COLUMN DiscussionSrcURL; diff --git a/announcements/resources/schemas/dbscripts/sqlserver/comm-create.sql b/announcements/resources/schemas/dbscripts/sqlserver/comm-create.sql deleted file mode 100644 index f8448ba4149..00000000000 --- a/announcements/resources/schemas/dbscripts/sqlserver/comm-create.sql +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - --- For each thread, select RowId, EntityId, Container, Body, RendererType, CreatedBy, and Created from the original post and add Title, Status, --- Expires, CreatedBy, and Created from either the most recent response or the original post, if no responses. -CREATE VIEW comm.Threads AS - SELECT threads.*, props.Title, props.AssignedTo, props.Status, props.Expires, props.CreatedBy AS ResponseCreatedBy, props.Created AS ResponseCreated FROM - ( - SELECT parents.RowId, parents.EntityId, parents.Container, parents.Body, parents.RendererType, parents.DiscussionSrcIdentifier, - parents.CreatedBy, parents.Created, parents.Modified, parents.LastIndexed, COALESCE(LastResponseId, RowId) AS LatestId, COALESCE(ResponseCount, 0) AS ResponseCount - FROM comm.Announcements parents LEFT OUTER JOIN - ( - SELECT Container, Parent, MAX(RowId) AS LastResponseId, COUNT(*) AS ResponseCount FROM comm.Announcements - WHERE Parent IS NOT NULL AND Approved > '1970-01-01' - GROUP BY Container, Parent - ) responses ON responses.Container = parents.Container AND responses.Parent = parents.EntityId - WHERE parents.parent IS NULL AND Approved > '1970-01-01' - ) threads - LEFT OUTER JOIN comm.Announcements props ON props.RowId = LatestId; - -GO - --- View that adds calculated Path and Depth columns -CREATE VIEW comm.PagePaths AS - WITH pages_cte AS ( - -- anchor - SELECT - p.RowId, p.EntityId, - p.CreatedBy, p.Created, - p.ModifiedBy, p.Modified, - p.Owner, p.Container, - p.Name, p.Parent, - p.DisplayOrder, p.PageVersionId, - p.ShowAttachments, p.LastIndexed, - p.ShouldIndex, - CAST(p.Name AS VARCHAR(2000)) AS Path, - CAST(p.Name AS VARCHAR(2000)) AS PathParts, - 0 AS Depth - FROM comm.Pages p - WHERE p.Parent IS NULL - - UNION ALL - - -- recursive part - SELECT - q.RowId, q.EntityId, - q.CreatedBy, q.Created, - q.ModifiedBy, q.Modified, - q.Owner, q.Container, - q.Name, q.Parent, - q.DisplayOrder, q.PageVersionId, - q.ShowAttachments, q.LastIndexed, - q.ShouldIndex, - CAST(previous.Path + '/' + q.Name AS VARCHAR(2000)) AS Path, - CAST(previous.PathParts + '{@~^' + q.Name AS VARCHAR(2000)) AS PathParts, - previous.Depth + 1 AS Depth - FROM comm.Pages q - JOIN pages_cte AS previous ON q.Parent = previous.RowId - ) - SELECT * from pages_cte; - -GO - --- View that joins each wiki with its current version (one row per wiki) -CREATE VIEW comm.CurrentWikiVersions AS - SELECT pv.RowId, p.EntityId, p.Container, p.Name, p.Path, p.PathParts, p.Depth, pv.Title, pv.Version, pv.Body, pv.RendererType, p.CreatedBy, p.Created, p.ModifiedBy, p.Modified - FROM comm.PagePaths p INNER JOIN comm.PageVersions pv ON p.PageVersionId = pv.RowId; - -GO - --- View that joins every wiki version with its parent (one row per wiki version). Report the wiki's Created & CreatedBy, --- but map the version's Created & CreatedBy to Modified & ModifiedBy, because that seems like the most useful mapping. -CREATE VIEW comm.AllWikiVersions AS - SELECT pv.RowId, p.EntityId, p.Container, p.Name, p.Path, p.PathParts, p.Depth, pv.Title, pv.Version, pv.Body, pv.RendererType, p.CreatedBy, p.Created, pv.CreatedBy AS ModifiedBy, pv.Created AS Modified - FROM comm.PageVersions pv INNER JOIN comm.PagePaths p ON pv.PageEntityId = p.EntityId; - -GO diff --git a/announcements/resources/schemas/dbscripts/sqlserver/comm-drop.sql b/announcements/resources/schemas/dbscripts/sqlserver/comm-drop.sql deleted file mode 100644 index 6ee34e43dc1..00000000000 --- a/announcements/resources/schemas/dbscripts/sqlserver/comm-drop.sql +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - --- DROP all views (current and obsolete) - --- NOTE: Don't remove any of these drop statements, even if we stop re-creating the view in *-create.sql. Drop statements must --- remain in place so we can correctly upgrade from older versions, which we commit to for two years after each release. - -EXEC core.fn_dropifexists 'Threads', 'comm', 'VIEW', NULL; -EXEC core.fn_dropifexists 'CurrentWikiVersions', 'comm', 'VIEW', NULL; -EXEC core.fn_dropifexists 'AllWikiVersions', 'comm', 'VIEW', NULL; -EXEC core.fn_dropifexists 'PagePaths', 'comm', 'VIEW', NULL; - diff --git a/api/module.properties b/api/module.properties index 6fdc9a83118..3a4620387c0 100644 --- a/api/module.properties +++ b/api/module.properties @@ -7,5 +7,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/api/src/org/labkey/api/assay/AbstractAssayProvider.java b/api/src/org/labkey/api/assay/AbstractAssayProvider.java index e244c6aff74..1261b5af12b 100644 --- a/api/src/org/labkey/api/assay/AbstractAssayProvider.java +++ b/api/src/org/labkey/api/assay/AbstractAssayProvider.java @@ -1807,11 +1807,6 @@ protected boolean hasFilterCriteria(ExpProtocol protocol, Domain resultsDomain) return false; } - @Override - public void removeFilterCriteriaForProperty(PropertyDescriptor pd) - { - } - public record AssayFileMoveData(ExpRun run, Container sourceContainer, String fieldName, File sourceFile, File targetFile) {} public record AssayMoveData(Map counts, Map> fileMovesByRunId) {} diff --git a/api/src/org/labkey/api/assay/AssayProvider.java b/api/src/org/labkey/api/assay/AssayProvider.java index 4c818396661..0b2aede759c 100644 --- a/api/src/org/labkey/api/assay/AssayProvider.java +++ b/api/src/org/labkey/api/assay/AssayProvider.java @@ -31,7 +31,6 @@ import org.labkey.api.exp.Handler; import org.labkey.api.exp.Lsid; import org.labkey.api.exp.ObjectProperty; -import org.labkey.api.exp.PropertyDescriptor; import org.labkey.api.exp.XarContext; import org.labkey.api.exp.api.ExpData; import org.labkey.api.exp.api.ExpExperiment; @@ -274,7 +273,6 @@ enum Scope @NotNull List getFilterCriteria(ExpProtocol protocol); boolean hasFilterCriteria(ExpProtocol protocol); - void removeFilterCriteriaForProperty(PropertyDescriptor pd); /** * @return the data type that this run creates for its analyzed results diff --git a/api/src/org/labkey/api/data/DbSchema.java b/api/src/org/labkey/api/data/DbSchema.java index 6d596300a60..a4adc6d3ea6 100644 --- a/api/src/org/labkey/api/data/DbSchema.java +++ b/api/src/org/labkey/api/data/DbSchema.java @@ -622,21 +622,9 @@ public void testDDLMethods() throws Exception SqlExecutor executor = new SqlExecutor(testSchema); - if (testSchema.getSqlDialect().isSqlServer()) - { - // test the 3 ways to create a schema on SQLServer - executor.execute("EXEC sp_addapprole 'testdrop', 'password'"); - executor.execute("CREATE SCHEMA testdrop2"); - executor.execute(testSchema.getSqlDialect().getCreateSchemaSql("testdrop3")); - } - else if (testSchema.getSqlDialect().isPostgreSQL()) - { - executor.execute("CREATE SCHEMA testdrop"); - executor.execute("CREATE SCHEMA testdrop2"); - executor.execute("CREATE SCHEMA testdrop3"); - } - else - return; + executor.execute("CREATE SCHEMA testdrop"); + executor.execute("CREATE SCHEMA testdrop2"); + executor.execute("CREATE SCHEMA testdrop3"); executor.execute("CREATE TABLE testdrop.T0 (c0 INT NOT NULL PRIMARY KEY)"); executor.execute("CREATE TABLE testdrop.T (c1 CHAR(1), fk_c0 INT REFERENCES testdrop.T0(c0))"); diff --git a/api/src/org/labkey/api/data/DbSequenceManager.java b/api/src/org/labkey/api/data/DbSequenceManager.java index 3b321af0b15..a868dfbed45 100644 --- a/api/src/org/labkey/api/data/DbSequenceManager.java +++ b/api/src/org/labkey/api/data/DbSequenceManager.java @@ -143,7 +143,7 @@ private static int ensure(Container c, String name, long id, boolean withUpdateL Integer rowId = executeAndMaybeReturnInteger(tinfo, getRowIdSql); - if (rowId != null && rowId > 0 && withUpdateLock && tinfo.getSqlDialect().isPostgreSQL()) + if (rowId != null && rowId > 0 && withUpdateLock) { SQLFragment lockRowSql = new SQLFragment("SELECT RowId FROM ").append(tinfo.getSelectName()); lockRowSql.append(" WHERE RowId = ?"); @@ -303,37 +303,18 @@ static Pair reserve(DbSequence sequence, long count) // Reselect the current value tinfo.getSqlDialect().addReselect(sql, tinfo.getColumn("Value"), null); - // Add locking appropriate to this dialect - addLocks(tinfo, sql); - long last = sequence.useCurrentTransaction() ? executeAndReturnLongInTraction(tinfo, sql) : executeAndReturnLong(tinfo, sql, Level.WARN); long first = last - count; return new Pair<>(first,last); } - private static void addLocks(TableInfo tinfo, SQLFragment updateSql) - { - if (tinfo.getSqlDialect().isSqlServer()) - updateSql.insert(updateSql.indexOf("SET"), "WITH (XLOCK, ROWLOCK) "); - } - - private static void addValueSql(SQLFragment sql, TableInfo tinfo, DbSequence sequence) { - SqlDialect dialect = tinfo.getSqlDialect(); - - if (dialect.isPostgreSQL()) - { - // SELECT with FOR UPDATE locks the row to ensure a true atomic update - SQLFragment selectForUpdate = new SQLFragment("SELECT Value FROM ").append(tinfo, "seq").append(" WHERE RowId = ? FOR UPDATE"); - selectForUpdate.add(sequence.getRowId()); - sql.append("(").append(selectForUpdate).append(")"); - } - else - { - sql.append("Value"); - } + // SELECT with FOR UPDATE locks the row to ensure a true atomic update + SQLFragment selectForUpdate = new SQLFragment("SELECT Value FROM ").append(tinfo, "seq").append(" WHERE RowId = ? FOR UPDATE"); + selectForUpdate.add(sequence.getRowId()); + sql.append("(").append(selectForUpdate).append(")"); } @@ -347,9 +328,6 @@ static void ensureMinimum(DbSequence sequence, long minimum) sql.add(sequence.getRowId()); sql.add(minimum); - // Add locking appropriate to this dialect - addLocks(tinfo, sql); - if (sequence.useCurrentTransaction()) new SqlExecutor(tinfo.getSchema()).execute(sql); else @@ -365,9 +343,6 @@ static void setSequenceValue(DbSequence sequence, long value) sql.add(value); sql.add(sequence.getRowId()); - // Add locking appropriate to this dialect - addLocks(tinfo, sql); - if (sequence.useCurrentTransaction()) new SqlExecutor(tinfo.getSchema()).execute(sql); else diff --git a/api/src/org/labkey/api/data/MaterializedQueryHelper.java b/api/src/org/labkey/api/data/MaterializedQueryHelper.java index 226abff3031..5e1c6c12457 100644 --- a/api/src/org/labkey/api/data/MaterializedQueryHelper.java +++ b/api/src/org/labkey/api/data/MaterializedQueryHelper.java @@ -162,9 +162,9 @@ boolean load(SQLFragment selectQuery, boolean isSelectInto) } else { - // UNLOGGED skips WAL when populating and indexing the table; only supported in PostgreSQL. + // UNLOGGED skips WAL when populating and indexing the table. selectInto = new SQLFragment("SELECT * INTO ") - .append(_mqh._unlogged && _mqh._scope.getSqlDialect().isPostgreSQL() ? "UNLOGGED " : "") + .append(_mqh._unlogged ? "UNLOGGED " : "") .appendIdentifier(temp.getName()).append(".").appendIdentifier(_tableName).append("\nFROM (\n"); selectInto.append(selectQuery); selectInto.append("\n) _sql_"); diff --git a/api/src/org/labkey/api/data/NameGenerator.java b/api/src/org/labkey/api/data/NameGenerator.java index b7671fe9160..5698a8a9220 100644 --- a/api/src/org/labkey/api/data/NameGenerator.java +++ b/api/src/org/labkey/api/data/NameGenerator.java @@ -107,7 +107,6 @@ public class NameGenerator public static final Pattern WITH_COUNTER_PATTERN = Pattern.compile(WITH_COUNTER_REGEX, Pattern.CASE_INSENSITIVE); public static final String WITH_COUNTER_NO_GAP_PARAM = "NoGap"; // named parameter to enforce continuity in sequence - public static final String EXPERIMENTAL_WITH_COUNTER = "UseStrictIncrementCounter"; // sql server public static final String EXPERIMENTAL_ALLOW_GAP_COUNTER = "AllowCounterGap"; // postgres /** diff --git a/api/src/org/labkey/api/data/ServerPrimaryKeyLock.java b/api/src/org/labkey/api/data/ServerPrimaryKeyLock.java index 6264b4de017..460ca21c957 100644 --- a/api/src/org/labkey/api/data/ServerPrimaryKeyLock.java +++ b/api/src/org/labkey/api/data/ServerPrimaryKeyLock.java @@ -43,8 +43,6 @@ public ServerPrimaryKeyLock(boolean failIfRowNotFound, TableInfo t, Object... pk scope = t.getSchema().getScope(); this.failIfRowNotFound = failIfRowNotFound; - if (scope.getSqlDialect().isSqlServer()) - forUpdate.append(" WITH (UPDLOCK)"); forUpdate.append("\nWHERE "); String and = " "; for (ColumnInfo pkColumn : pkColumns) @@ -52,8 +50,7 @@ public ServerPrimaryKeyLock(boolean failIfRowNotFound, TableInfo t, Object... pk forUpdate.append(and); forUpdate.appendIdentifier(pkColumn.getSelectIdentifier()).append("=?").add(pkValues[forUpdate.getParamsArray().length]); } - if (scope.getSqlDialect().isPostgreSQL()) - forUpdate.append("\nFOR UPDATE"); + forUpdate.append("\nFOR UPDATE"); } @Override diff --git a/api/src/org/labkey/api/data/SqlSelectorTestCase.java b/api/src/org/labkey/api/data/SqlSelectorTestCase.java index 6c38fefc2d0..52fcdfc99c9 100644 --- a/api/src/org/labkey/api/data/SqlSelectorTestCase.java +++ b/api/src/org/labkey/api/data/SqlSelectorTestCase.java @@ -190,22 +190,15 @@ public void testJdbcUncached() throws SQLException try (Connection conn = scope.getConnection()) { // Default (no explicit setJdbcCaching() call) now auto-disables JDBC caching when it's safe: a separate, - // uncached Connection on PostgreSQL (outside a transaction), but still the shared Connection on SQL Server. + // uncached Connection outside a transaction. try (Connection conn2 = new SqlSelector(scope, "SELECT RowId, Body FROM comm.Announcements").getConnection()) { - if (scope.getSqlDialect().isPostgreSQL()) - { - assertNotEquals(conn, conn2); - assertEquals(TRANSACTION_READ_UNCOMMITTED, conn2.getTransactionIsolation()); - assertFalse(conn2.getAutoCommit()); - } - else - { - assertEquals(conn, conn2); - } + assertNotEquals(conn, conn2); + assertEquals(TRANSACTION_READ_UNCOMMITTED, conn2.getTransactionIsolation()); + assertFalse(conn2.getAutoCommit()); } - // Explicitly requesting caching shares the connection, even on PostgreSQL + // Explicitly requesting caching shares the connection try (Connection conn2 = new SqlSelector(scope, "SELECT RowId, Body FROM comm.Announcements").setJdbcCaching(true).getConnection()) { assertEquals(conn, conn2); @@ -217,28 +210,19 @@ public void testJdbcUncached() throws SQLException assertEquals(conn, conn2); } - // Here we expect a different Connection object on PostgreSQL, but still shared on SQL Server + // Here we expect a different Connection object try (Connection conn2 = new SqlSelector(scope, "SELECT RowId, Body FROM comm.Announcements").setJdbcCaching(false).getConnection()) { - if (scope.getSqlDialect().isPostgreSQL()) - { - assertNotEquals(conn, conn2); - assertEquals(TRANSACTION_READ_UNCOMMITTED, conn2.getTransactionIsolation()); - assertFalse(conn2.getAutoCommit()); - } - else - { - assertEquals(conn, conn2); - assertEquals(TRANSACTION_READ_COMMITTED, conn2.getTransactionIsolation()); - assertTrue(conn2.getAutoCommit()); - } + assertNotEquals(conn, conn2); + assertEquals(TRANSACTION_READ_UNCOMMITTED, conn2.getTransactionIsolation()); + assertFalse(conn2.getAutoCommit()); } } // A "self-contained" read (getArrayList(), forEach(), getRowCount(), etc., which fully consume and close the // ResultSet within the call) borrows the thread's shared connection rather than a dedicated one, so nested - // queries reuse it and connection-local state stays visible. On PostgreSQL the outermost borrower puts it into - // no-caching mode and restores it on release; on SQL Server it's simply the shared connection. + // queries reuse it and connection-local state stays visible. The outermost borrower puts it into no-caching + // mode and restores it on release. Connection borrowed = new SqlSelector(scope, "SELECT RowId, Body FROM comm.Announcements").getConnection(true); try { @@ -254,11 +238,8 @@ public void testJdbcUncached() throws SQLException assertEquals(borrowed, nested); } - if (scope.getSqlDialect().isPostgreSQL()) - { - assertEquals(TRANSACTION_READ_UNCOMMITTED, borrowed.getTransactionIsolation()); - assertFalse(borrowed.getAutoCommit()); - } + assertEquals(TRANSACTION_READ_UNCOMMITTED, borrowed.getTransactionIsolation()); + assertFalse(borrowed.getAutoCommit()); } finally { diff --git a/api/src/org/labkey/api/data/Table.java b/api/src/org/labkey/api/data/Table.java index 1d9f8dcaa58..58df845c624 100644 --- a/api/src/org/labkey/api/data/Table.java +++ b/api/src/org/labkey/api/data/Table.java @@ -1744,8 +1744,8 @@ public static ParameterMapStatement deleteStatement(Connection conn, TableInfo t DomainKind domainKind = tableDelete.getDomainKind(); if (null != domain && null != domainKind && StringUtils.isEmpty(domainKind.getStorageSchemaName())) { - if (!d.isPostgreSQL() && !d.isSqlServer()) - throw new IllegalArgumentException("Domains are only supported for sql server and postgres"); + if (!d.isPostgreSQL()) + throw new IllegalArgumentException("Domains are only supported for postgres"); String objectIdColumnName = updatable.getObjectIdColumnName(); String objectURIColumnName = updatable.getObjectURIColumnName(); diff --git a/api/src/org/labkey/api/data/TableChange.java b/api/src/org/labkey/api/data/TableChange.java index 0501f3bccc1..33476bef601 100644 --- a/api/src/org/labkey/api/data/TableChange.java +++ b/api/src/org/labkey/api/data/TableChange.java @@ -153,17 +153,7 @@ public void updateResizeIndices() { List columnNames = index.columns().stream().map(ColumnInfo::getName).collect(Collectors.toList()); - // CONSIDER: Move this re-classification of the non-unique index as a unique index into SchemaColumnMetaData.loadUniqueIndices() - // SQLServer creates a non-unique index for single large text columns with a "_hashed_" prefix. - // The uniqueness is enforced by a database trigger. - boolean unique = index.indexType() == TableInfo.IndexType.Unique || - (schema.getSqlDialect().isSqlServer() && columnNames.size() == 1 && columnNames.getFirst().startsWith(PropertyStorageSpec.HASHED_COLUMN_PREFIX)); - - // remove the _hashed_ column prefix for SQLServer - if (schema.getSqlDialect().isSqlServer() && unique) - columnNames = columnNames.stream().map(s -> s.startsWith(PropertyStorageSpec.HASHED_COLUMN_PREFIX) ? s.substring(PropertyStorageSpec.HASHED_COLUMN_PREFIX.length()) : s).collect(Collectors.toList()); - - Index idx = new Index(unique, columnNames); + Index idx = new Index(index.indexType() == TableInfo.IndexType.Unique, columnNames); for (String columnName : columnNames) { diff --git a/api/src/org/labkey/api/data/generator/DataGenerator.java b/api/src/org/labkey/api/data/generator/DataGenerator.java index ff7c1d0585d..3b9ff8067df 100644 --- a/api/src/org/labkey/api/data/generator/DataGenerator.java +++ b/api/src/org/labkey/api/data/generator/DataGenerator.java @@ -560,7 +560,7 @@ private SQLFragment limitFromOffsetSqlFrag(TableInfo tableInfo, String columns, SQLFragment sql = new SQLFragment("SELECT " + columns); SQLFragment fromSql = new SQLFragment(" FROM ").append(tableInfo, "dc"); - return dialect.limitRows(sql, fromSql, null, dialect.isSqlServer() ? new SQLFragment("ORDER By RowId") : null, null, limit, totalCount > limit ? randomLong(0, totalCount-limit) : 0); + return dialect.limitRows(sql, fromSql, null, null, null, limit, totalCount > limit ? randomLong(0, totalCount-limit) : 0); } public List> selectExistingSamples(ExpSampleType sampleType, int limit, long totalSampleCount) diff --git a/api/src/org/labkey/api/data/validator/DateValidator.java b/api/src/org/labkey/api/data/validator/DateValidator.java index 1656b3346e6..b3ba8d924a0 100644 --- a/api/src/org/labkey/api/data/validator/DateValidator.java +++ b/api/src/org/labkey/api/data/validator/DateValidator.java @@ -56,17 +56,13 @@ public class DateValidator extends AbstractColumnValidator private final long _maxDate; private final String _errMsg; - public DateValidator(String columnName) - { - this(columnName, MIN_TIMESTAMP_SQLSERVER, MAX_TIMESTAMP_SQLSERVER, ERRMSG_SQLSERVER); - } - public DateValidator(String columnName, @Nullable SqlDialect dialect) { + // Only an external SQL Server data source gets the narrow DATETIME range; the primary database is PostgreSQL this(columnName, - null != dialect && dialect.isPostgreSQL() ? MIN_TIMESTAMP_POSTGRESQL : MIN_TIMESTAMP_SQLSERVER, - null != dialect && dialect.isPostgreSQL() ? MAX_TIMESTAMP_POSTGRESQL : MAX_TIMESTAMP_SQLSERVER, - null != dialect && dialect.isPostgreSQL() ? ERRMSG_POSTGRESQL : ERRMSG_SQLSERVER); + null != dialect && dialect.isSqlServer() ? MIN_TIMESTAMP_SQLSERVER : MIN_TIMESTAMP_POSTGRESQL, + null != dialect && dialect.isSqlServer() ? MAX_TIMESTAMP_SQLSERVER : MAX_TIMESTAMP_POSTGRESQL, + null != dialect && dialect.isSqlServer() ? ERRMSG_SQLSERVER : ERRMSG_POSTGRESQL); } private DateValidator(String columnName, long minDate, long maxDate, String errMsg) diff --git a/api/src/org/labkey/api/dataiterator/TableInsertUpdateDataIterator.java b/api/src/org/labkey/api/dataiterator/TableInsertUpdateDataIterator.java index b0f589d65a5..de0d9853258 100644 --- a/api/src/org/labkey/api/dataiterator/TableInsertUpdateDataIterator.java +++ b/api/src/org/labkey/api/dataiterator/TableInsertUpdateDataIterator.java @@ -422,12 +422,7 @@ private void setAutoIncrement(INSERT bound) if (autoIncCol == null) return; - if (_scope.getSqlDialect().isSqlServer()) - { - SQLFragment check = new SQLFragment("SET IDENTITY_INSERT ").append(t).append(" ").append(bound.toString()); - new SqlExecutor(_scope, _conn).execute(check); - } - else if (_scope.getSqlDialect().isPostgreSQL() && bound == INSERT.OFF) + if (_scope.getSqlDialect().isPostgreSQL() && bound == INSERT.OFF) { // Update the sequence for the serial column with the max+1 and handle empty tables if (autoIncCol.getSelectIdentifier() != null) diff --git a/api/src/org/labkey/api/exp/Lsid.java b/api/src/org/labkey/api/exp/Lsid.java index 299eb644e25..f54b88044ab 100644 --- a/api/src/org/labkey/api/exp/Lsid.java +++ b/api/src/org/labkey/api/exp/Lsid.java @@ -26,9 +26,7 @@ import org.junit.Test; import org.labkey.api.data.Builder; import org.labkey.api.data.SQLFragment; -import org.labkey.api.data.dialect.SqlDialect; import org.labkey.api.settings.AppProps; -import org.labkey.api.util.GUID; import org.labkey.api.util.Pair; import java.net.URI; @@ -138,36 +136,16 @@ private static String[] parseLsid(@Nullable String s) } // Keep in sync with LSID_REGEX (above). Note: AttachmentServiceImpl.TestCase.testLsidGuidExtraction tests this. - public static Pair getSqlExpressionToExtractObjectId(SQLFragment lsidExpression, SqlDialect dialect) + public static Pair getSqlExpressionToExtractObjectId(SQLFragment lsidExpression) { - String objectId = GUID.SQL_LIKE_GUID_PATTERN; - - if (dialect.isPostgreSQL()) - { - // PostgreSQL SUBSTRING supports simple regular expressions. This captures all the text from the fourth - // colon to the end of the string (or to the fifth colon, if present). - SQLFragment expression = new SQLFragment("SUBSTRING(") - .append(lsidExpression) - .append(" FROM '%urn:lsid:%:%:#\"[0-9a-f\\-]{36}#\":?%' FOR '#')"); - SQLFragment where = new SQLFragment(lsidExpression).append(" SIMILAR TO '%urn:lsid:%:%:[0-9a-f\\-]{36}:?%'"); - - return new Pair<>(expression, where); - } - - if (dialect.isSqlServer()) - { - // SQL Server doesn't support regular expressions - SQLFragment expression = new SQLFragment("SUBSTRING(") - .append(lsidExpression) - .append(", PATINDEX('%:" + objectId + "%', ") - .append(lsidExpression) - .append(") + 1, 36)"); - SQLFragment where = new SQLFragment(lsidExpression).append(" LIKE '%urn:lsid:%:%:" + objectId + "%'"); - - return new Pair<>(expression, where); - } - - throw new IllegalStateException("Unsupported SqlDialect: " + dialect.getProductName()); + // PostgreSQL SUBSTRING supports simple regular expressions. This captures all the text from the fourth + // colon to the end of the string (or to the fifth colon, if present). + SQLFragment expression = new SQLFragment("SUBSTRING(") + .append(lsidExpression) + .append(" FROM '%urn:lsid:%:%:#\"[0-9a-f\\-]{36}#\":?%' FOR '#')"); + SQLFragment where = new SQLFragment(lsidExpression).append(" SIMILAR TO '%urn:lsid:%:%:[0-9a-f\\-]{36}:?%'"); + + return new Pair<>(expression, where); } public String getSrc() diff --git a/api/src/org/labkey/api/exp/OntologyManager.java b/api/src/org/labkey/api/exp/OntologyManager.java index 68969304aa9..d0bfbd2bb94 100644 --- a/api/src/org/labkey/api/exp/OntologyManager.java +++ b/api/src/org/labkey/api/exp/OntologyManager.java @@ -1952,8 +1952,7 @@ public static DomainDescriptor ensureDomainDescriptor(DomainDescriptor ddIn) .append("WHERE NOT EXISTS (SELECT * FROM ").append(getTinfoDomainDescriptor(),"x").append(" WHERE x.DomainURI=? AND x.Project=?)\n") .add(ddIn.getDomainURI()).add(ddIn.getProject()); // belt and suspenders approach to avoiding constraint violation exception - if (expSchema.getSqlDialect().isPostgreSQL()) - insert.append(" ON CONFLICT ON CONSTRAINT uq_domaindescriptor DO NOTHING"); + insert.append(" ON CONFLICT ON CONSTRAINT uq_domaindescriptor DO NOTHING"); int count; try (var tx = expSchema.getScope().ensureTransaction()) { diff --git a/api/src/org/labkey/api/exp/PropertyColumn.java b/api/src/org/labkey/api/exp/PropertyColumn.java index 6cb8f03384e..86d35419b70 100644 --- a/api/src/org/labkey/api/exp/PropertyColumn.java +++ b/api/src/org/labkey/api/exp/PropertyColumn.java @@ -15,7 +15,6 @@ */ package org.labkey.api.exp; -import org.apache.commons.lang3.Strings; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.labkey.api.data.BaseColumnInfo; @@ -312,40 +311,6 @@ public SQLFragment getJoinCondition(String tableAliasName) return strJoinNoContainer; } - @Override - protected SQLFragment getJoinCondition(String tableAliasName, ColumnInfo fk, ColumnInfo pk, boolean equalOrIsNull) - { - // hack: issue 16263, on sql server entityid is a uniqueidentifier type, we need to force a cast - // when using an entityid to join to an objecturi - boolean addEntityIdCast = Strings.CI.equals("entityid", fk.getSqlTypeName()) && - Strings.CI.equals("lsidtype", pk.getSqlTypeName()) && - getSqlDialect().isSqlServer(); - - if (addEntityIdCast) - { - SQLFragment condition = new SQLFragment(); - if (equalOrIsNull) - condition.append("("); - - SQLFragment fkSql = fk.getValueSql(tableAliasName); - condition.append("CAST((").append(fkSql).append(") AS VARCHAR(36))"); - condition.append(" = "); - - SQLFragment pkSql = pk.getValueSql(getTableAlias(tableAliasName)); - condition.append(pkSql); - - if (equalOrIsNull) - { - condition.append(" OR (").append(fkSql).append(" IS NULL"); - condition.append(" AND ").append(pkSql).append(" IS NULL))"); - } - - return condition; - } - else - return super.getJoinCondition(tableAliasName, fk, pk, equalOrIsNull); - } - @Override public String getTableAlias(String baseAlias) { diff --git a/api/src/org/labkey/api/exp/PropertyDescriptor.java b/api/src/org/labkey/api/exp/PropertyDescriptor.java index f25ae1d41e7..6f9a02828e9 100644 --- a/api/src/org/labkey/api/exp/PropertyDescriptor.java +++ b/api/src/org/labkey/api/exp/PropertyDescriptor.java @@ -234,7 +234,7 @@ public DatabaseIdentifier getLegalSelectName(SqlDialect dialect) public static DatabaseIdentifier getLegalSelectNameFromStorageName(SqlDialect dialect, String storageName) { String legalName = dialect.makeLegalIdentifier(storageName); - if (!storageName.equals(legalName) && dialect.isPostgreSQL()) + if (!storageName.equals(legalName)) { storageName = storageName.toLowerCase(); legalName = dialect.makeLegalIdentifier(storageName); // Our PG code deep down makes these lowercase, so we need to, too diff --git a/api/src/org/labkey/api/exp/property/DomainUtil.java b/api/src/org/labkey/api/exp/property/DomainUtil.java index 40ba5211c8f..dc3ad61edb7 100644 --- a/api/src/org/labkey/api/exp/property/DomainUtil.java +++ b/api/src/org/labkey/api/exp/property/DomainUtil.java @@ -39,7 +39,6 @@ import org.labkey.api.data.ContainerFilter; import org.labkey.api.data.ContainerManager; import org.labkey.api.data.ContainerService; -import org.labkey.api.data.CoreSchema; import org.labkey.api.data.DatabaseIdentifier; import org.labkey.api.data.NameGenerator; import org.labkey.api.data.PHI; @@ -442,9 +441,7 @@ public static List getCalculatedFieldsForDefaultView(@NotNull TableInf public static boolean allowMultiChoice(DomainKind kind) { - if (!kind.allowMultiChoiceProperties()) - return false; - return CoreSchema.getInstance().getSqlDialect().isPostgreSQL(); + return kind.allowMultiChoiceProperties(); } private static GWTDomain getDomain(Domain dd) diff --git a/api/src/org/labkey/api/files/TableUpdaterFileListener.java b/api/src/org/labkey/api/files/TableUpdaterFileListener.java index df6842b2be5..5b027d0ea43 100644 --- a/api/src/org/labkey/api/files/TableUpdaterFileListener.java +++ b/api/src/org/labkey/api/files/TableUpdaterFileListener.java @@ -229,7 +229,6 @@ public int fileMoved(@NotNull Path src, @NotNull Path dest, @Nullable User user, // Build up SQL that can be used for both the file and any children SQLFragment sharedSQL = new SQLFragment("UPDATE "); sharedSQL.append(_table); - sharedSQL.append(_table.getSqlDialect().isSqlServer() ? " WITH (UPDLOCK)" : ""); sharedSQL.append(" SET "); if (_table.getColumn("Modified") != null) { diff --git a/api/src/org/labkey/api/query/AliasManager.java b/api/src/org/labkey/api/query/AliasManager.java index 82933c66ef9..2a1a5815e20 100644 --- a/api/src/org/labkey/api/query/AliasManager.java +++ b/api/src/org/labkey/api/query/AliasManager.java @@ -191,20 +191,10 @@ public void testLongNameTruncation() String truncatedNums2 = m.decideAlias(nums); String truncatedNums3 = m.decideAlias(nums); - if (dialect.isSqlServer()) - { - assertEquals(125, truncatedNums1.length()); - assertEquals(126, truncatedNums2.length()); - assertEquals(126, truncatedNums3.length()); - assertEquals("X1483201190789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", truncatedNums1); - } - else - { - assertEquals(60, truncatedNums1.length()); - assertEquals(61, truncatedNums2.length()); - assertEquals(61, truncatedNums3.length()); - assertEquals("X14832011902345678901234567890123456789012345678901234567890", truncatedNums1); - } + assertEquals(60, truncatedNums1.length()); + assertEquals(61, truncatedNums2.length()); + assertEquals(61, truncatedNums3.length()); + assertEquals("X14832011902345678901234567890123456789012345678901234567890", truncatedNums1); // Not an interesting test at the moment since every non-alphanumeric gets replaced with _. But this will // become interesting if we start allowing Unicode characters in alias names in the future. diff --git a/api/src/org/labkey/api/security/SecurityManager.java b/api/src/org/labkey/api/security/SecurityManager.java index 1f9cc19f85a..9b7ee70e03f 100644 --- a/api/src/org/labkey/api/security/SecurityManager.java +++ b/api/src/org/labkey/api/security/SecurityManager.java @@ -1126,11 +1126,7 @@ else if (email.getEmailAddress().indexOf("@") > 0) displayName = displayName.replace("@"," "); displayName = StringUtils.trimToEmpty(displayName); - // Issue 25813: if two users are being inserted at the same time through the addUser method above, we can get deadlock on SQLServer so we - // actively lock when doing this select to prevent it from promoting a lock up the chain. SQLFragment select = new SQLFragment("SELECT UserId FROM ").append(core.getTableInfoUsersData()); - if (core.getSchema().getScope().getSqlDialect().isSqlServer()) - select.append(" WITH (UPDLOCK)"); select.append(" WHERE DisplayName = ? AND UserId != ?"); select.add(displayName); select.add(userId); diff --git a/api/src/org/labkey/api/view/Portal.java b/api/src/org/labkey/api/view/Portal.java index 48072bd404b..6fff4611961 100644 --- a/api/src/org/labkey/api/view/Portal.java +++ b/api/src/org/labkey/api/view/Portal.java @@ -1037,7 +1037,7 @@ private static void _insertOrUpdate(TableInfo portalTable, PortalPage p, boolean .append(portalTable) .append(" WHERE Container = ?)") .add(p.getContainer()) - .append(getSqlDialect().isPostgreSQL() ? " FOR UPDATE)" : ")"); + .append(" FOR UPDATE)"); count = new SqlExecutor(portalTable.getSchema()).execute(insertSQL); } @@ -1055,42 +1055,27 @@ private static void _insertOrUpdate(TableInfo portalTable, PortalPage p, boolean .append(" WHERE Container = ? AND NOT (PageId = ?))\nTHEN ? ELSE ").appendIdentifier(columnIndex.getSelectIdentifier()).append(" END\n") .add(p.getContainer()).add(p.getPageId()).add(p.getIndex()); - if (portalTable.getSqlDialect().isPostgreSQL()) + List updateColumns = new ArrayList<>(); + updateColumns.add("Index"); + updateColumns.add("Caption"); + updateColumns.add("Hidden"); + updateColumns.add("Type"); + updateColumns.add("Action"); + updateColumns.add("TargetFolder"); + updateColumns.add("Permanent"); + updateColumns.add("Properties"); + + updateSQL.append("\nSET ("); + String comma = ""; + for (String name : updateColumns) { - List updateColumns = new ArrayList<>(); - updateColumns.add("Index"); - updateColumns.add("Caption"); - updateColumns.add("Hidden"); - updateColumns.add("Type"); - updateColumns.add("Action"); - updateColumns.add("TargetFolder"); - updateColumns.add("Permanent"); - updateColumns.add("Properties"); - - updateSQL.append("\nSET ("); - String comma = ""; - for (String name : updateColumns) - { - updateSQL.append(comma).appendIdentifier(portalTable.getColumn(name).getSelectIdentifier()); - comma = ","; - } - updateSQL.append(") =\n") - .append("(") - .append(indexSQL) - .append(", ?, ?, ?, ?, ?, ?, ?)\n"); - } - else - { // SQL Server - updateSQL.append("\nSET ") - .appendIdentifier(columnIndex.getSelectIdentifier()).append(" = ").append(indexSQL).append(", ") - .append("Caption").append(" = ?, ") - .append("Hidden").append(" = ?, ") - .append("Type").append(" = ?, ") - .append("Action").append(" = ?, ") - .append("TargetFolder").append(" = ?, ") - .append("Permanent").append(" = ?, ") - .append("Properties").append(" = ? \n"); + updateSQL.append(comma).appendIdentifier(portalTable.getColumn(name).getSelectIdentifier()); + comma = ","; } + updateSQL.append(") =\n") + .append("(") + .append(indexSQL) + .append(", ?, ?, ?, ?, ?, ?, ?)\n"); updateSQL.add(p.getCaption()).add(p.isHidden()).add(p.getType()).add(p.getAction()) .add(p.getTargetFolder()).add(p.isPermanent()).add(p.getProperties()) diff --git a/assay/api-src/org/labkey/api/assay/AssayResultDomainKind.java b/assay/api-src/org/labkey/api/assay/AssayResultDomainKind.java index af87f14db13..52b838a9200 100644 --- a/assay/api-src/org/labkey/api/assay/AssayResultDomainKind.java +++ b/assay/api-src/org/labkey/api/assay/AssayResultDomainKind.java @@ -24,8 +24,6 @@ import org.labkey.api.data.JdbcType; import org.labkey.api.data.PropertyStorageSpec; import org.labkey.api.dataiterator.SimpleTranslator.SpecialColumn; -import org.labkey.api.exp.OntologyManager; -import org.labkey.api.exp.PropertyDescriptor; import org.labkey.api.exp.api.ExpProtocol; import org.labkey.api.exp.property.Domain; import org.labkey.api.exp.property.DomainUtil; @@ -155,25 +153,6 @@ public boolean allowCalculatedFields() return true; } - @Override - public void deletePropertyDescriptor(Domain domain, User user, PropertyDescriptor pd) - { - super.deletePropertyDescriptor(domain, user, pd); - - // 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 the "CREATE TABLE assay.FilterCriteria" - // statement in assay schema upgrade scripts. - if (!OntologyManager.getSqlDialect().isSqlServer()) - return; - - Pair pair = findProviderAndProtocol(domain); - if (pair == null) - return; - - pair.first.removeFilterCriteriaForProperty(pd); - } - @Override public String getDomainFileDirectory() { diff --git a/assay/module.properties b/assay/module.properties index 510e33a467d..f354fde7ca5 100644 --- a/assay/module.properties +++ b/assay/module.properties @@ -5,5 +5,4 @@ Description: Provides services and other APIs that assay modules call to impleme URL: https://www.labkey.org/Documentation/wiki-page.view?name=instrumentData License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true 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 deleted file mode 100644 index 17f5eb527c9..00000000000 --- a/assay/resources/schemas/dbscripts/sqlserver/assay-0.000-25.000.sql +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.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 --- 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-25.000-25.001.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-25.000-25.001.sql deleted file mode 100644 index a1de4cfb404..00000000000 --- a/assay/resources/schemas/dbscripts/sqlserver/assay-25.000-25.001.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.executeJavaUpgradeCode 'migrateReplicateGroups'; diff --git a/assay/resources/schemas/dbscripts/sqlserver/assay-25.001-25.002.sql b/assay/resources/schemas/dbscripts/sqlserver/assay-25.001-25.002.sql deleted file mode 100644 index 38d1492f2ca..00000000000 --- a/assay/resources/schemas/dbscripts/sqlserver/assay-25.001-25.002.sql +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- This index overlaps with uq_platesetedge_fromplate_toplate -DROP INDEX ix_platesetedge_fromplatesetid ON assay.PlateSetEdge; --- This index overlaps with uq_wellgroup_plateid_typename_name -DROP INDEX ix_wellgroup_plateid ON assay.WellGroup; --- This index overlaps with uq_well_plateid_row_col -DROP INDEX ix_well_plateid ON assay.Well; --- This index overlaps with uq_plate_container_name_template -DROP INDEX ix_plate_container ON assay.Plate; diff --git a/assay/src/org/labkey/assay/AssayIntegrationTestCase.jsp b/assay/src/org/labkey/assay/AssayIntegrationTestCase.jsp index e3fc5005a9c..cc8bef2ba40 100644 --- a/assay/src/org/labkey/assay/AssayIntegrationTestCase.jsp +++ b/assay/src/org/labkey/assay/AssayIntegrationTestCase.jsp @@ -580,7 +580,7 @@ updated.put("ResultProp", 200); updated.put("RowId", resultRowId); errors = new BatchValidationException(); - Thread.sleep(schema.getDbSchema().getSqlDialect().isSqlServer() ? 100 : 5); // SQL Server timestamps aren't granular enough to guarantee different modified time + Thread.sleep(5); resultsQUS.updateRows(user, c, Collections.singletonList(updated), null, errors, null, null); // verify result created matches run's created in query table, but result modified now differs from run's created diff --git a/assay/src/org/labkey/assay/TsvAssayProvider.java b/assay/src/org/labkey/assay/TsvAssayProvider.java index 05105f9bb72..ef5dc70951c 100644 --- a/assay/src/org/labkey/assay/TsvAssayProvider.java +++ b/assay/src/org/labkey/assay/TsvAssayProvider.java @@ -59,7 +59,6 @@ import org.labkey.api.data.TableSelector; import org.labkey.api.exp.Lsid; import org.labkey.api.exp.ObjectProperty; -import org.labkey.api.exp.PropertyDescriptor; import org.labkey.api.exp.PropertyType; import org.labkey.api.exp.XarContext; import org.labkey.api.exp.api.ExpData; @@ -749,19 +748,6 @@ private void updateFilterCriteria( } } - @Override - public void removeFilterCriteriaForProperty(PropertyDescriptor pd) - { - assert AssayDbSchema.getInstance().getSchema().getScope().isTransactionActive(); - - var table = AssayDbSchema.getInstance().getTableInfoFilterCriteria(); - var sql = new SQLFragment("DELETE FROM ").append(table) - .append(" WHERE (PropertyId = ? OR ReferencePropertyId = ?)") - .addAll(pd.getPropertyId(), pd.getPropertyId()); - - new SqlExecutor(table.getSchema()).execute(sql); - } - private static boolean isResultsDomain(GWTDomain domain) { return domain != null && domain.getDomainURI().contains(":" + ExpProtocol.AssayDomainTypes.Result.getPrefix() + "."); diff --git a/assay/src/org/labkey/assay/plate/PlateManager.java b/assay/src/org/labkey/assay/plate/PlateManager.java index 502cde71a82..5c904cf209a 100644 --- a/assay/src/org/labkey/assay/plate/PlateManager.java +++ b/assay/src/org/labkey/assay/plate/PlateManager.java @@ -2569,9 +2569,7 @@ public Container getPlateMetadataDomainContainer(Container container) String insertSql = "INSERT INTO " + AssayDbSchema.getInstance().getTableInfoPlateSetProperty() + " (plateSetId, propertyId, propertyURI, FieldKey)" + - " VALUES (?, CAST(? AS INT), " + - (DbScope.getLabKeyScope().getSqlDialect().isSqlServer() ? "CAST(? AS VARCHAR(300))" : "CAST(? AS VARCHAR)") + - ", CAST(? AS VARCHAR))"; + " VALUES (?, CAST(? AS INT), CAST(? AS VARCHAR), CAST(? AS VARCHAR))"; Table.batchExecute(AssayDbSchema.getInstance().getSchema(), insertSql, insertedValues); transaction.addCommitTask(() -> PlateCache.uncache(container, plateSet), DbScope.CommitTaskOption.POSTCOMMIT); diff --git a/audit/module.properties b/audit/module.properties index da031be2f65..c1b48e6ab8e 100644 --- a/audit/module.properties +++ b/audit/module.properties @@ -5,5 +5,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/audit/resources/schemas/dbscripts/sqlserver/audit-0.000-23.000.sql b/audit/resources/schemas/dbscripts/sqlserver/audit-0.000-23.000.sql deleted file mode 100644 index 2211f1a0b86..00000000000 --- a/audit/resources/schemas/dbscripts/sqlserver/audit-0.000-23.000.sql +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2019-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE SCHEMA audit; -GO - -CREATE TABLE audit.AuditLog -( - RowId BIGINT IDENTITY(1,1) NOT NULL, - Key1 NVARCHAR(1000) NULL, - Key2 NVARCHAR(1000) NULL, - Key3 NVARCHAR(1000) NULL, - IntKey1 INT NULL, - IntKey2 INT NULL, - IntKey3 INT NULL, - Comment NVARCHAR(500), - EventType NVARCHAR(64), - CreatedBy USERID NOT NULL, - Created DATETIME, - ContainerId ENTITYID NOT NULL, - EntityId ENTITYID NULL, - Lsid LSIDtype, - ProjectId ENTITYID, - ImpersonatedBy USERID NULL, - - CONSTRAINT PK_AuditLog PRIMARY KEY (RowId) -); -CREATE INDEX IX_Audit_Container ON audit.AuditLog(ContainerId); - -CREATE INDEX IX_AuditLog_IntKey1 ON audit.AuditLog(IntKey1); -ALTER TABLE audit.AuditLog DROP CONSTRAINT PK_AuditLog; -CREATE CLUSTERED INDEX IX_AuditLog_EventType_Created ON audit.AuditLog(EventType, Created DESC); --- NONCLUSTERED -ALTER TABLE audit.AuditLog ADD CONSTRAINT PK_AuditLog PRIMARY KEY (RowId); - -GO diff --git a/audit/resources/schemas/dbscripts/sqlserver/audit-25.000-25.001.sql b/audit/resources/schemas/dbscripts/sqlserver/audit-25.000-25.001.sql deleted file mode 100644 index 4a4c693a500..00000000000 --- a/audit/resources/schemas/dbscripts/sqlserver/audit-25.000-25.001.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- This old table hasn't been used since we migrated the audit log to provisioned tables (in 2013!) -DROP TABLE IF EXISTS audit.AuditLog; diff --git a/core/module.properties b/core/module.properties index 0731d77b149..f6eddb9cc4b 100644 --- a/core/module.properties +++ b/core/module.properties @@ -9,5 +9,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/core/resources/schemas/dbscripts/sqlserver/core-0.000-25.000.sql b/core/resources/schemas/dbscripts/sqlserver/core-0.000-25.000.sql deleted file mode 100644 index a49bef6adef..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-0.000-25.000.sql +++ /dev/null @@ -1,922 +0,0 @@ -/* - * Copyright (c) 2019-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE SCHEMA core; -GO -CREATE SCHEMA temp; -GO - -EXEC sp_addtype 'ENTITYID', 'UNIQUEIDENTIFIER'; -EXEC sp_addtype 'USERID', 'INT'; -GO - --- for JDBC Login support, validates email/password, --- UserId is stored in the Principals table --- LDAP authenticated users are not in this table - -CREATE TABLE core.Logins -( - Email VARCHAR(255) NULL, -- No longer used. A later script will drop this column. - Crypt VARCHAR(64) NOT NULL, - Verification VARCHAR(64), - LastChanged DATETIME NULL, - PreviousCrypts VARCHAR(1000), - RequestedEmail NVARCHAR(255), - VerificationTimeout DATETIME, - UserId USERID NOT NULL, - - CONSTRAINT PK_Logins PRIMARY KEY (UserId) -); - --- Principals is used for managing security related information --- It is not used for validating login, that requires an 'external' --- process, either using SMB, LDAP, JDBC etc (see Logins table) --- --- It does not contain contact info and other generic user visible data - -CREATE TABLE core.Principals -( - UserId USERID IDENTITY(1000,1), -- user or group - Container ENTITYID, -- NULL for all users, NOT NULL for _ALL_ groups - OwnerId ENTITYID NULL, - Name NVARCHAR(64), -- email (must contain @ and .), group name (no punctuation), or hidden (no @) - Type CHAR(1), -- 'u'=user 'g'=group (NYI 'r'=role, 'm'=managed(module specific) - Active BIT NOT NULL DEFAULT 1, - - CONSTRAINT PK_Principals PRIMARY KEY (UserId), - CONSTRAINT UQ_Principals_Container_Name_OwnerId UNIQUE (Container, Name, OwnerId) -); - --- maps users to groups -CREATE TABLE core.Members -( - UserId USERID, - GroupId USERID, - - CONSTRAINT PK_Members PRIMARY KEY (UserId, GroupId) -); - -CREATE TABLE core.UsersData -( - -- standard fields - _ts TIMESTAMP, - EntityId ENTITYID DEFAULT NEWID(), - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Owner USERID NULL, - - UserId USERID, - - DisplayName NVARCHAR(64) NOT NULL, - FirstName NVARCHAR(64) NULL, - LastName NVARCHAR(64) NULL, - Phone NVARCHAR(64) NULL, - Mobile NVARCHAR(64) NULL, - Pager NVARCHAR(64) NULL, - IM NVARCHAR(64) NULL, - Description NVARCHAR(255), - LastLogin DATETIME, - ExpirationDate DATETIME, - - CONSTRAINT PK_UsersData PRIMARY KEY (UserId), - CONSTRAINT UQ_DisplayName UNIQUE (DisplayName) -); - -ALTER TABLE core.UsersData ADD System BIT NOT NULL DEFAULT 0; -ALTER TABLE core.UsersData ADD LastActivity DATETIME NULL; - -CREATE TABLE core.Containers -( - _ts TIMESTAMP, - RowId INT IDENTITY(1, 1), - EntityId ENTITYID DEFAULT NEWID(), - CreatedBy USERID, - Created DATETIME, - - Parent ENTITYID, - Name NVARCHAR(255), - SortOrder INTEGER NOT NULL DEFAULT 0, - Searchable BIT NOT NULL DEFAULT 1, -- Should this container's content be searched during multi-container searches? - - Description NVARCHAR(4000), - Title NVARCHAR(1000), - Type VARCHAR(16) CONSTRAINT DF_Container_Type DEFAULT 'normal' NOT NULL, - - CONSTRAINT UQ_Containers_EntityId UNIQUE (EntityId), - CONSTRAINT UQ_Containers_Parent_Name UNIQUE (Parent, Name), - CONSTRAINT FK_Containers_Containers FOREIGN KEY (Parent) REFERENCES core.Containers(EntityId) -); - -CREATE INDEX IX_Containers_Parent_Entity ON core.Containers(Parent, EntityId); - -ALTER TABLE core.Containers ADD LockState VARCHAR(25) NULL; -ALTER TABLE core.Containers ADD ExpirationDate DATETIME NULL; -ALTER TABLE core.Containers ADD FileRootSize BIGINT; -ALTER TABLE core.Containers ADD FileRootLastCrawled DATETIME; - --- Adding a PK on RowId seemed like a good idea, but it broke existing lookups to core.Containers and other assumptions. --- We could add a PK on EntityId, but that column is currently nullable. For now, we'll just live without a PK. -ALTER TABLE core.Containers ADD CONSTRAINT UQ_Containers_RowId UNIQUE CLUSTERED (RowId); - --- table for all modules -CREATE TABLE core.Modules -( - Name NVARCHAR(255), - ClassName NVARCHAR(255), - SchemaVersion FLOAT NULL, - Enabled BIT DEFAULT 1, - AutoUninstall BIT NOT NULL DEFAULT 0, -- TRUE means LabKey should uninstall this module (drop schemas, delete SqlScripts rows, delete Modules rows), if it no longer exists - Schemas NVARCHAR(4000) NULL, -- Schemas managed by this module; LabKey will drop these schemas when a module marked AutoUninstall = TRUE is missing - - CONSTRAINT PK_Modules PRIMARY KEY (Name) -); - --- keep track of sql scripts that have been run in each module -CREATE TABLE core.SqlScripts -( - -- standard fields - _ts TIMESTAMP, - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - - ModuleName NVARCHAR(100), - FileName NVARCHAR(300), - - CONSTRAINT PK_SqlScripts PRIMARY KEY (ModuleName, FileName) -); - --- generic table for all attached docs -CREATE TABLE core.Documents -( - -- standard fields - _ts TIMESTAMP, - RowId INT IDENTITY(1,1), - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Owner USERID NULL, - - Container ENTITYID NOT NULL, -- Container of parent, if parent has no ACLs - Parent ENTITYID NOT NULL, - DocumentName NVARCHAR(195), --filename - - DocumentSize INT DEFAULT -1, - DocumentType VARCHAR(500) DEFAULT 'text/plain', -- Needs to be large enough to handle new Office document mime-types - Document IMAGE, -- ContentType LIKE application/* - - LastIndexed DATETIME NULL, - - CONSTRAINT PK_Documents PRIMARY KEY (RowId), - CONSTRAINT UQ_Documents_Parent_DocumentName UNIQUE (Parent, DocumentName) -); - -CREATE INDEX IX_Documents_Container ON core.Documents(Container); -CREATE INDEX IX_Documents_Parent ON core.Documents(Parent); - -CREATE TABLE core.Report -( - RowId INT IDENTITY(1,1) NOT NULL, - ReportKey NVARCHAR(255), - CreatedBy USERID, - ModifiedBy USERID, - Created DATETIME, - Modified DATETIME, - ContainerId ENTITYID NOT NULL, - EntityId ENTITYID NULL, - DescriptorXML TEXT, - ReportOwner INT, - Flags INT NOT NULL DEFAULT 0, - CategoryId INT, - DisplayOrder INT NOT NULL DEFAULT 0, - ContentModified DATETIME NOT NULL, - - CONSTRAINT PK_Report PRIMARY KEY (RowId), - CONSTRAINT FK_Report_ContainerId FOREIGN KEY (ContainerId) REFERENCES core.Containers (EntityId) -); - -CREATE INDEX IDX_Report_ContainerId ON core.Report(ContainerId); - -CREATE TABLE core.ContainerAliases -( - Path NVARCHAR(255) NOT NULL, - ContainerId ENTITYID NOT NULL, - - CONSTRAINT UK_ContainerAliases_Paths UNIQUE (Path), - CONSTRAINT FK_ContainerAliases_Containers FOREIGN KEY (ContainerId) REFERENCES core.Containers(EntityId) -); - -ALTER TABLE core.containeraliases ALTER COLUMN path NVARCHAR(4000); - -CREATE TABLE core.MappedDirectories -( - EntityId ENTITYID NOT NULL, - Container ENTITYID NOT NULL, - Relative BIT NOT NULL, - Name NVARCHAR(80), - Path NVARCHAR(255), - - CONSTRAINT PK_MappedDirecctories PRIMARY KEY (EntityId), - CONSTRAINT UQ_MappedDirectories UNIQUE (Container,Name) -); - -CREATE TABLE core.Policies -( - ResourceId ENTITYID NOT NULL, - ResourceClass VARCHAR(1000), - Container ENTITYID NOT NULL, - Modified DATETIME NOT NULL, - - CONSTRAINT PK_Policies PRIMARY KEY(ResourceId) -); - -CREATE TABLE core.RoleAssignments -( - ResourceId ENTITYID NOT NULL, - UserId USERID NOT NULL, - Role VARCHAR(500) NOT NULL, - - CONSTRAINT PK_RoleAssignments PRIMARY KEY(ResourceId, UserId, Role), - CONSTRAINT FK_RA_P FOREIGN KEY(ResourceId) REFERENCES core.Policies(ResourceId), - CONSTRAINT FK_RA_UP FOREIGN KEY(UserId) REFERENCES core.Principals(UserId) -); - -CREATE TABLE core.MvIndicators -( - Container ENTITYID NOT NULL, - MvIndicator VARCHAR(64) NOT NULL, - Label VARCHAR(255), - - CONSTRAINT PK_MvIndicators_Container_MvIndicator PRIMARY KEY (Container, MvIndicator) -); - --- CONSIDER: eventually switch to entityid PK/FK -CREATE TABLE core.PortalPages -( - RowId INT IDENTITY(1,1) NOT NULL, - EntityId ENTITYID NOT NULL, - Container ENTITYID NOT NULL, - PageId VARCHAR(50) NOT NULL, - "index" INTEGER NOT NULL, - Caption VARCHAR(64), - Hidden BIT NOT NULL DEFAULT 0, - Type VARCHAR(20), -- 'portal', 'folder', 'action' - -- associate page with a registered folder type - -- folderType VARCHAR(64), - Action VARCHAR(200), -- type='action' see DetailsURL - TargetFolder ENTITYID, -- type=='folder' - Permanent BIT NOT NULL DEFAULT 0, -- may not be renamed,hidden,deleted (w/o changing folder type) - Properties TEXT, - - CONSTRAINT PK_PortalPages PRIMARY KEY (RowId), - CONSTRAINT FK_PortalPages_Containers FOREIGN KEY (Container) REFERENCES core.Containers (EntityId) -); - -CREATE INDEX IX_PortalPages_EntityId ON core.PortalPages(EntityId); - -CREATE TABLE core.PortalWebParts -( - RowId INT IDENTITY(1, 1) NOT NULL, - Container ENTITYID NOT NULL, - [Index] INT NOT NULL, - Name VARCHAR(64), - Location VARCHAR(16), -- 'body', 'left', 'right' - Properties TEXT, -- url encoded properties - Permanent BIT NOT NULL DEFAULT 0, - Permission VARCHAR(256) NULL, - PermissionContainer ENTITYID NULL, - PortalPageId INT NOT NULL, - - CONSTRAINT PK_PortalWebParts PRIMARY KEY (RowId), - CONSTRAINT FK_PortalWebParts_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId), - CONSTRAINT FK_PortalWebParts_PermissionContainer FOREIGN KEY (PermissionContainer) REFERENCES core.Containers (EntityId) ON UPDATE NO ACTION ON DELETE SET NULL, - CONSTRAINT FK_PortalWebPartPages FOREIGN KEY (PortalPageId) REFERENCES core.PortalPages (rowId) -); - --- Add an index and FK on the Container column -CREATE INDEX IX_PortalWebParts ON core.PortalWebParts(Container); - --- represents a grouping category for reports and datasets -CREATE TABLE core.ViewCategory -( - RowId INT IDENTITY(1,1) NOT NULL, - Container ENTITYID NOT NULL, - CreatedBy USERID, - Created DATETIME DEFAULT getdate(), - ModifiedBy USERID, - Modified DATETIME DEFAULT getdate(), - - Label NVARCHAR(200) NOT NULL, - DisplayOrder INT NOT NULL DEFAULT 0, - - Parent INT, - - CONSTRAINT pk_viewCategory PRIMARY KEY (RowId), - CONSTRAINT uq_container_label_parent UNIQUE (Container, Label, Parent), - CONSTRAINT FK_ViewCategory_Parent FOREIGN KEY (Parent) REFERENCES core.ViewCategory(RowId) -); - -CREATE TABLE core.DbSequences -( - RowId INT IDENTITY, - Container ENTITYID NOT NULL, - Name VARCHAR(500) NOT NULL, - Id INTEGER NOT NULL, - Value BIGINT NOT NULL, - - CONSTRAINT PK_DbSequences PRIMARY KEY (RowId), - CONSTRAINT UQ_DbSequences_Container_Name_Id UNIQUE (Container, Name, Id) -); - -CREATE TABLE core.ShortURL -( - RowId INT IDENTITY(1, 1), - EntityId ENTITYID NOT NULL, - ShortURL NVARCHAR(255) NOT NULL, - FullURL NVARCHAR(4000) NOT NULL, - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - - CONSTRAINT PK_ShortURL PRIMARY KEY (RowId), - CONSTRAINT UQ_ShortURL_EntityId UNIQUE (EntityId), - CONSTRAINT UQ_ShortURL_ShortURL UNIQUE (ShortURL) -); - -CREATE TABLE core.Notifications -( - RowId INT IDENTITY(1,1) NOT NULL, - Container ENTITYID NOT NULL, - CreatedBy USERID, - Created DATETIME, - - UserId USERID NOT NULL, - ObjectId NVARCHAR(64) NOT NULL, - Type NVARCHAR(200) NOT NULL, - ReadOn DATETIME, - ActionLinkText NVARCHAR(2000), - ActionLinkURL NVARCHAR(4000), - Content NVARCHAR(MAX), - ContentType NVARCHAR(100), - - CONSTRAINT PK_Notifications PRIMARY KEY (RowId), - CONSTRAINT FK_Notifications_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId), - CONSTRAINT UQ_Notifications_ContainerUserObjectType UNIQUE (Container, UserId, ObjectId, Type) -); - -CREATE INDEX IX_Notification_User ON core.Notifications(UserId); - -CREATE TABLE core.DataStates -( - RowId INT IDENTITY(1,1), - Label NVARCHAR(64) NULL, - Description NVARCHAR(500) NULL, - Container ENTITYID NOT NULL, - PublicData BIT NOT NULL, - - CONSTRAINT PK_QCState PRIMARY KEY (RowId), - CONSTRAINT UQ_QCState_Label UNIQUE(Label, Container) -); - -ALTER TABLE core.DataStates ADD StateType NVARCHAR(20); -ALTER TABLE core.datastates ADD Color NVARCHAR(7) NULL; - -CREATE TABLE core.APIKeys -( - RowId INT IDENTITY(1, 1), - CreatedBy USERID, - Created DATETIME, - Crypt VARCHAR(100), - Expiration DATETIME NULL, - - CONSTRAINT PK_APIKeys PRIMARY KEY (RowId), - CONSTRAINT UQ_CRYPT UNIQUE (Crypt) -); - -ALTER TABLE core.APIKeys ADD Description NVARCHAR(256); -ALTER TABLE core.APIKeys ADD LastUsed DATETIME; - -CREATE TABLE core.ReportEngines -( - RowId INT IDENTITY(1,1) NOT NULL, - Name NVARCHAR(255) NOT NULL, - CreatedBy USERID, - ModifiedBy USERID, - Created DATETIME, - Modified DATETIME, - - Enabled BIT NOT NULL DEFAULT 0, - Type NVARCHAR(64) NOT NULL, - Description NVARCHAR(255), - Configuration NVARCHAR(MAX), - - CONSTRAINT PK_ReportEngines PRIMARY KEY (RowId), - CONSTRAINT UQ_Name_Type UNIQUE (Name, Type) -); - -CREATE TABLE core.ReportEngineMap -( - EngineId INTEGER NOT NULL, - Container ENTITYID NOT NULL, - EngineContext NVARCHAR(64) NOT NULL DEFAULT 'report', - - CONSTRAINT PK_ReportEngineMap PRIMARY KEY (EngineId, Container, EngineContext), - CONSTRAINT FK_ReportEngineMap_ReportEngines FOREIGN KEY (EngineId) REFERENCES core.ReportEngines (RowId) -); - -CREATE TABLE core.AuthenticationConfigurations -( - RowId INT IDENTITY(1,1), - EntityId ENTITYID NOT NULL, - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - - Provider NVARCHAR(64) NOT NULL, - Description NVARCHAR(255) NOT NULL, - Enabled BIT NOT NULL, - AutoRedirect BIT NOT NULL DEFAULT 0, - SortOrder SMALLINT NOT NULL DEFAULT 32767, -- ensure that new configurations appear at the bottom of the list by default - Properties NVARCHAR(MAX), - EncryptedProperties NVARCHAR(MAX), - - CONSTRAINT PK_AuthenticationConfigurations PRIMARY KEY (RowId) -); - -CREATE TABLE core.EmailOptions -( - EmailOptionId INT NOT NULL, - EmailOption NVARCHAR(50), - Type NVARCHAR(60) NOT NULL DEFAULT 'messages', - - CONSTRAINT PK_EmailOptions PRIMARY KEY (EmailOptionId) -); - -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption) VALUES (0, 'No Email'); -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption) VALUES (1, 'All conversations'); -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption) VALUES (2, 'My conversations'); -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption) VALUES (257, 'Daily digest of all conversations'); -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption) VALUES (258, 'Daily digest of my conversations'); - --- new file email notification options -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption, Type) VALUES (512, 'No Email', 'files'); -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption, Type) VALUES (513, '15 minute digest', 'files'); -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption, Type) VALUES (514, 'Daily digest', 'files'); - --- sample manager email notification options -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption, Type) VALUES (701, 'No Email', 'samplemanager'); -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption, Type) VALUES (702, 'All emails', 'samplemanager'); - --- labbook email notification options -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption, Type) VALUES (801, 'No Email', 'labbook'); -INSERT INTO core.EmailOptions (EmailOptionId, EmailOption, Type) VALUES (802, 'All emails', 'labbook'); - -CREATE TABLE core.EmailPrefs -( - Container ENTITYID, - UserId USERID, - EmailOptionId INT NOT NULL, - LastModifiedBy USERID, - Type NVARCHAR(60) NOT NULL DEFAULT 'messages', - SrcIdentifier NVARCHAR(100) NOT NULL, -- allow subscriptions to multiple forums within a single container - - CONSTRAINT PK_EmailPrefs PRIMARY KEY (Container, UserId, Type, SrcIdentifier), - CONSTRAINT FK_EmailPrefs_Containers FOREIGN KEY (Container) REFERENCES core.Containers (EntityId), - CONSTRAINT FK_EmailPrefs_Principals FOREIGN KEY (UserId) REFERENCES core.Principals (UserId), - CONSTRAINT FK_EmailPrefs_EmailOptions FOREIGN KEY (EmailOptionId) REFERENCES core.EmailOptions (EmailOptionId) -); - -GO - --- This empty stored procedure doesn't directly change the database, but calling it from a sql script signals the --- script runner to invoke the specified method at this point in the script running process. See implementations of --- the UpgradeCode interface for more details. -CREATE PROCEDURE core.executeJavaUpgradeCode(@Name VARCHAR(255)) AS -BEGIN - DECLARE @notice VARCHAR(255) - SET @notice = 'Empty function that signals script runner to execute Java initialization code. See implementations of UpgradeCode.java.' -END; - -GO - --- This empty stored procedure is a synonym for core.executeJavaUpgradeCode(), but is meant to denote Java code that is used to --- initialize data in a schema (e.g., pre-populating a table with values), not transform existing data. We mark these cases with --- a different procedure name because our bootstrap scripts still need to invoke them, as opposed to invocations of upgrade code --- which we remove from bootstrap scripts. See implementations of the UpgradeCode interface to find the initialization code. -CREATE PROCEDURE core.executeJavaInitializationCode(@Name VARCHAR(255)) AS -BEGIN -DECLARE @notice VARCHAR(255) -SET @notice = 'Empty function that signals script runner to execute initialization Java code. See implementations of UpgradeCode.java.' -END; - -GO - -CREATE FUNCTION core.fnCalculateAge(@startDate DATETIME, @endDate DATETIME) RETURNS INT -AS - BEGIN -/* - Simple function to calculate the age (number of years, rounded down) between two dates - Returns NULL if either startDate or endDate is NULL - - No check is made that endDate is after startDate; the calculation is invalid in this case. -*/ - DECLARE @age INT; - - IF @startDate IS NULL OR @endDate IS NULL SET @age = NULL - ELSE - BEGIN - SET @age = YEAR(@endDate) - YEAR(@startDate) - - CASE WHEN MONTH(@endDate) < MONTH(@startDate) OR - (MONTH(@endDate) = MONTH(@startDate) AND DAY(@endDate) < DAY(@startDate)) - THEN 1 - ELSE 0 - END - END - - RETURN @age - END; - -GO - --- An empty stored procedure (similar to executeJavaUpgradeCode) that, when detected by the script runner, --- imports a tabular data file (TSV, XLSX, etc.) into the specified table. -CREATE PROCEDURE core.bulkImport(@schema VARCHAR(200), @table VARCHAR(200), @filename VARCHAR(200), @preserveEmptyString bit = 0) AS - BEGIN - DECLARE @notice VARCHAR(255) - SET @notice = 'Empty function that signals script runner to bulk import a file into a table.' - END; - -GO - -CREATE PROCEDURE [core].[fn_dropifexists] (@objname VARCHAR(250), @objschema VARCHAR(50), @objtype VARCHAR(50), @subobjname VARCHAR(250) = NULL, @printCmds BIT = 0) -AS -BEGIN - /* - Procedure to safely drop most database object types without error if the object does not exist. Schema deletion - will cascade to the tables and programability objects in that schema. Column deletion will cascade to any keys, - constraints, and indexes on the column. - Usage: - EXEC core.fn_dropifexists objname, objschema, objtype, subobjname, printCmds - where: - objname Required. For TABLE, VIEW, PROCEDURE, FUNCTION, AGGREGATE, SYNONYM, this is the name of the object to be dropped - for SCHEMA, specify '*' to drop all dependent objects, or NULL to drop an empty schema - for INDEX, CONSTRAINT, DEFAULT, or COLUMN, specify the name of the table - objschema Required. The name of the schema for the object, or the schema being dropped - objtype Required. The type of object being dropped. Valid values are TABLE, VIEW, INDEX, CONSTRAINT, DEFAULT, SCHEMA, PROCEDURE, FUNCTION, AGGREGATE, SYNONYM, COLUMN - subobjtype Optional. When dropping INDEX, CONSTRAINT, DEFAULT, or COLUMN, the name of the object being dropped - printCmds Optional, 1 or 0. If 1, the cascading drop commands for SCHEMA and COLUMN will be printed for debugging purposes - - Note for implementors: Names that are part of SQL commands executed below should be bracketed to handle names that - have spaces, special characters, or reserved words. Names that are used in comparisons, in this code and in WHERE - clauses, must not be bracketed. @fullname is bracketed, since it's only used in SQL commands. All other vars are not - bracketed since they're often used in comparisons. When referencing @objname, @objschema, @subobjname, etc. be sure - to add brackets where required. - */ - DECLARE @ret_code INTEGER - DECLARE @fullname VARCHAR(500) - DECLARE @fkConstName sysname, @fkTableName sysname, @fkSchema sysname - SELECT @ret_code = 0 - SELECT @fullname = ('[' + @objschema + '].[' + @objname + ']') -- @fullname is always bracketed, to handle names that are reserved words, etc. - IF (UPPER(@objtype)) = 'TABLE' - BEGIN - IF OBJECTPROPERTY(OBJECT_ID(@fullname), 'IsTable') =1 - BEGIN - EXEC('DROP TABLE ' + @fullname ) - SELECT @ret_code = 1 - END - ELSE IF @objname LIKE '##%' AND OBJECT_ID('tempdb.dbo.[' + @objname + ']') IS NOT NULL - BEGIN - EXEC('DROP TABLE [' + @objname + ']') - SELECT @ret_code = 1 - END - END - ELSE IF (UPPER(@objtype)) = 'VIEW' - BEGIN - IF OBJECTPROPERTY(OBJECT_ID(@fullname), 'IsView') =1 - BEGIN - EXEC('DROP VIEW ' + @fullname ) - SELECT @ret_code =1 - END - END - ELSE IF (UPPER(@objtype)) = 'INDEX' - BEGIN - DECLARE @fullername VARCHAR(500) - SELECT @fullername = @fullname + '.[' + @subobjname + ']' -- Unlikely to require brackets, but doesn't hurt - IF INDEXPROPERTY(OBJECT_ID(@fullname), @subobjname, 'IndexID') IS NOT NULL - BEGIN - EXEC('DROP INDEX ' + @fullername ) - SELECT @ret_code =1 - END - ELSE IF EXISTS (SELECT * FROM sys.indexes si - WHERE si.name = @subobjname - AND OBJECT_NAME(si.object_id) <> @objname) - BEGIN - RAISERROR ('Index does not belong to specified table ' , 16, 1) - RETURN @ret_code - END - END - ELSE IF (UPPER(@objtype)) = 'CONSTRAINT' - BEGIN - IF OBJECTPROPERTY(OBJECT_ID(@objschema + '.' + @subobjname), 'IsConstraint') = 1 - BEGIN - EXEC('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @subobjname + ']') - SELECT @ret_code =1 - END - END - ELSE IF (UPPER(@objtype)) = 'DEFAULT' - BEGIN - DECLARE @DEFAULT sysname - SELECT @DEFAULT = s.name - FROM sys.objects s - join sys.columns c ON s.object_id = c.default_object_id - WHERE - s.type = 'D' - and c.object_id = OBJECT_ID(@fullname) - and c.name = @subobjname - - IF @DEFAULT IS NOT NULL AND OBJECTPROPERTY(OBJECT_ID(@objschema + '.' + @DEFAULT), 'IsConstraint') = 1 - BEGIN - EXEC('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @DEFAULT + ']') - if (@printCmds = 1) PRINT('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @DEFAULT + ']') - SELECT @ret_code =1 - END - END - ELSE IF (UPPER(@objtype)) = 'SCHEMA' - BEGIN - DECLARE @schemaid INT, @principalid int - - SELECT @schemaid=schema_id, @principalid=principal_id - FROM sys.schemas - WHERE name = @objschema - - IF @schemaid IS NOT NULL - BEGIN - IF (@objname is NOT NULL AND @objname NOT IN ('', '*')) - BEGIN - RAISERROR ('Invalid @objname for @objtype of SCHEMA; must be either "*" (to drop all dependent objects) or NULL (for dropping empty schema)' , 16, 1) - RETURN @ret_code - END - ELSE IF (@objname = '*' ) - BEGIN - DECLARE fkCursor CURSOR LOCAL for - SELECT object_name(sfk.object_id) as fk_constraint_name, object_name(sfk.parent_object_id) as fk_table_name, - schema_name(sfk.schema_id) as fk_schema_name - FROM sys.foreign_keys sfk - INNER JOIN sys.objects fso ON (sfk.referenced_object_id = fso.object_id) - WHERE fso.schema_id=@schemaid - AND sfk.type = 'F' - - OPEN fkCursor - FETCH NEXT FROM fkCursor INTO @fkConstName, @fkTableName, @fkSchema - WHILE @@fetch_status = 0 - BEGIN - SELECT @fullname = '[' + @fkSchema + '].[' +@fkTableName + ']' - EXEC('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @fkConstName + ']') - if (@printCmds = 1) PRINT('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @fkConstName + ']') - - FETCH NEXT FROM fkCursor INTO @fkConstName, @fkTableName, @fkSchema - END - CLOSE fkCursor - DEALLOCATE fkCursor - - DECLARE @soName sysname, @parent INT, @type CHAR(2), @fkschemaid int - DECLARE soCursor CURSOR LOCAL for - SELECT so.name, so.type, so.parent_object_id, so.schema_id - FROM sys.objects so - WHERE (so.schema_id=@schemaid) - ORDER BY (CASE WHEN so.type='V' THEN 1 - WHEN so.type='P' THEN 2 - WHEN so.type IN ('FN', 'IF', 'TF', 'FS', 'FT') THEN 3 - WHEN so.type='AF' THEN 4 - WHEN so.type='U' THEN 5 - WHEN so.type='SN' THEN 6 - ELSE 7 - END) - OPEN soCursor - FETCH NEXT FROM soCursor INTO @soName, @type, @parent, @fkschemaid - WHILE @@fetch_status = 0 - BEGIN - SELECT @fullname = '[' + @objschema + '].[' + @soName + ']' - IF (@type = 'V') - BEGIN - EXEC('DROP VIEW ' + @fullname) - if (@printCmds = 1) PRINT('DROP VIEW ' + @fullname) - END - ELSE IF (@type = 'P') - BEGIN - EXEC('DROP PROCEDURE ' + @fullname) - if (@printCmds = 1) PRINT('DROP PROCEDURE ' + @fullname) - END - ELSE IF (@type IN ('FN', 'IF', 'TF', 'FS', 'FT')) - BEGIN - EXEC('DROP FUNCTION ' + @fullname) - if (@printCmds = 1) PRINT('DROP FUNCTION ' + @fullname) - END - ELSE IF (@type = 'AF') - BEGIN - EXEC('DROP AGGREGATE ' + @fullname) - if (@printCmds = 1) PRINT('DROP AGGREGATE ' + @fullname) - END - ELSE IF (@type = 'U') - BEGIN - EXEC('DROP TABLE ' + @fullname) - if (@printCmds = 1) PRINT('DROP TABLE ' + @fullname) - END - ELSE IF (@type = 'SN') - BEGIN - EXEC('DROP SYNONYM ' + @fullname) - if (@printCmds = 1) PRINT('DROP SYNONYM ' + @fullname) - END - ELSE - BEGIN - DECLARE @msg NVARCHAR(255) - SELECT @msg=' Found object of type: ' + @type + ' name: ' + @fullname + ' in this schema. Schema not dropped. ' - RAISERROR (@msg, 16, 1) - RETURN @ret_code - END - FETCH NEXT FROM soCursor INTO @soName, @type, @parent, @fkschemaid - END - CLOSE soCursor - DEALLOCATE soCursor - END - - IF (@objSchema != 'dbo') - BEGIN - DECLARE @approlename sysname - SELECT @approlename = name - FROM sys.database_principals - WHERE principal_id=@principalid AND type='A' - - IF (@approlename IS NOT NULL) - BEGIN - EXEC sp_dropapprole @approlename - if (@printCmds = 1) PRINT ('sp_dropapprole '+ @approlename) - END - ELSE - BEGIN - EXEC('DROP SCHEMA [' + @objschema + ']') - if (@printCmds = 1) PRINT('DROP SCHEMA [' + @objschema + ']') - END - END - SELECT @ret_code =1 - END - END - ELSE IF (UPPER(@objtype)) = 'PROCEDURE' - BEGIN - IF (@objschema = 'sys') - BEGIN - RAISERROR ('Invalid @objschema, not attempting to drop sys object', 16, 1) - RETURN @ret_code - END - IF OBJECTPROPERTY(OBJECT_ID(@fullname), 'IsProcedure') =1 - BEGIN - EXEC('DROP PROCEDURE ' + @fullname ) - SELECT @ret_code =1 - END - END - ELSE IF (UPPER(@objtype)) = 'FUNCTION' - BEGIN - IF EXISTS (SELECT 1 FROM sys.objects o JOIN sys.schemas s ON o.schema_id = s.schema_id WHERE s.name = @objschema AND o.name = @objname AND o.type IN ('FN', 'IF', 'TF', 'FS', 'FT')) - BEGIN - EXEC('DROP FUNCTION ' + @fullname ) - SELECT @ret_code =1 - END - END - ELSE IF (UPPER(@objtype)) = 'AGGREGATE' - BEGIN - IF EXISTS (SELECT 1 FROM sys.objects o JOIN sys.schemas s ON o.schema_id = s.schema_id WHERE s.name = @objschema AND o.name = @objname AND o.type = 'AF') - BEGIN - EXEC('DROP AGGREGATE ' + @fullname ) - SELECT @ret_code =1 - END - END - ELSE IF (UPPER(@objtype)) = 'SYNONYM' - BEGIN - IF EXISTS (SELECT 1 FROM sys.objects o JOIN sys.schemas s ON o.schema_id = s.schema_id WHERE s.name = @objschema AND o.name = @objname AND o.type = 'SN') - BEGIN - EXEC('DROP SYNONYM ' + @fullname ) - SELECT @ret_code =1 - END - END - ELSE IF (UPPER(@objtype)) = 'COLUMN' - BEGIN - DECLARE @tableID INT - SET @tableID = OBJECT_ID(@fullname) - IF EXISTS (SELECT 1 FROM sys.columns WHERE Name = N'' + @subobjname AND Object_ID = @tableID) - BEGIN - -- Drop any indexes and constraints on the column - DECLARE @index SYSNAME - DECLARE cur_indexes CURSOR FOR - SELECT - i.Name - FROM - sys.indexes i - INNER JOIN - sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id - INNER JOIN - sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id - WHERE - c.name = @subobjname - AND is_primary_key = 0 - AND i.object_id = @tableID - - DECLARE fkCursor CURSOR LOCAL for - SELECT object_name(fk.object_id), object_name(fkc.parent_object_id), schema_name(fk.schema_id) - FROM sys.foreign_keys fk JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id - JOIN sys.columns c ON fkc.referenced_object_id = c.object_id AND c.column_id = fkc.referenced_column_id - WHERE fk.referenced_object_id = @tableID AND c.name = @subobjname - - BEGIN TRANSACTION - BEGIN TRY - -- Drop indexes - OPEN cur_indexes - FETCH NEXT FROM cur_indexes INTO @index - WHILE (@@FETCH_STATUS = 0) - BEGIN - if (@printCmds = 1) PRINT('DROP INDEX [' + @index + '] ON ' + @fullname + '-- index drop') - EXEC('DROP INDEX [' + @index + '] ON ' + @fullname) - FETCH NEXT FROM cur_indexes INTO @index - END - CLOSE cur_indexes - - -- Drop foreign keys - DECLARE @fkFullName sysname - OPEN fkCursor - FETCH NEXT FROM fkCursor INTO @fkConstName, @fkTableName, @fkSchema - WHILE @@fetch_status = 0 - BEGIN - SELECT @fkFullName = '[' + @fkSchema + '].[' +@fkTableName + ']' - if (@printCmds = 1) PRINT('ALTER TABLE ' + @fkFullName + ' DROP CONSTRAINT [' + @fkConstName + '] -- FK drop') - EXEC('ALTER TABLE ' + @fkFullname + ' DROP CONSTRAINT [' + @fkConstName + ']') - FETCH NEXT FROM fkCursor INTO @fkConstName, @fkTableName, @fkSchema - END - CLOSE fkCursor - - -- Drop default constraint on column - DECLARE @ConstraintName nvarchar(200) - SELECT @ConstraintName = Name FROM SYS.DEFAULT_CONSTRAINTS WHERE PARENT_OBJECT_ID = @tableID AND PARENT_COLUMN_ID = (SELECT column_id FROM sys.columns WHERE NAME = N'' + @subobjname AND object_id = @tableID) - IF @ConstraintName IS NOT NULL - BEGIN - if (@printCmds = 1) PRINT ('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @ConstraintName + '] -- default constraint drop') - EXEC('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @ConstraintName + ']') - END - - -- Drop other constraints, including PK - SET @ConstraintName = NULL - while 0=0 begin - set @constraintName = ( - select top 1 constraint_name - from information_schema.constraint_column_usage - where TABLE_SCHEMA = @objschema and table_name = @objname and column_name = @subobjname ) - if @constraintName is null break - if (@printCmds = 1) PRINT ('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @ConstraintName + '] -- other constraint drop') - exec ('ALTER TABLE ' + @fullname + ' DROP CONSTRAINT [' + @ConstraintName + ']') - end - - -- Now drop the column - if (@printCmds = 1) PRINT ('ALTER TABLE ' + @fullname + ' DROP COLUMN [' + @subobjname + ']') - EXEC('ALTER TABLE ' + @fullname + ' DROP COLUMN [' + @subobjname + ']') - SELECT @ret_code =1 - - DEALLOCATE cur_indexes - DEALLOCATE fkCursor - COMMIT TRANSACTION - END TRY - BEGIN CATCH - ROLLBACK TRANSACTION - DEALLOCATE cur_indexes - DEALLOCATE fkCursor - - DECLARE @error varchar(max) - SET @error = 'Error dropping column %s. The column has not been changed. This procedure can automatically drop indexes, foreign keys or primary keys, defaults, and other constraints on a column, but not other objects such as triggers or rules. - Original error from SQL Server was: ' + ERROR_MESSAGE() - RAISERROR(@error, 16, 1, @subobjname) - END CATCH - END - END - ELSE - RAISERROR('Invalid object type - %s Valid values are TABLE, VIEW, INDEX, CONSTRAINT, DEFAULT, SCHEMA, PROCEDURE, FUNCTION, AGGREGATE, SYNONYM, COLUMN', 16, 1, @objtype ) - - RETURN @ret_code; -END; - -GO diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.000-25.001.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.000-25.001.sql deleted file mode 100644 index d5ea35357a2..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.000-25.001.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.executeJavaUpgradeCode 'migrateAllowedExternalConnectionHosts'; diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.001-25.002.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.001-25.002.sql deleted file mode 100644 index 70bf000c55b..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.001-25.002.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -DROP PROCEDURE IF EXISTS core.bulkImport; \ No newline at end of file diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.002-25.003.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.002-25.003.sql deleted file mode 100644 index f651653efb0..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.002-25.003.sql +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- persist deferred upgrade methods, potentially across server sessions -CREATE TABLE core.UpgradeSteps -( - RowId INT IDENTITY(1,1) NOT NULL, - ModuleName NVARCHAR(255) NOT NULL, - Script NVARCHAR(255) NOT NULL, - MethodName NVARCHAR(255) NOT NULL, - Created DATETIME NOT NULL, - Executed DATETIME NULL, - - CONSTRAINT PK_UpgradeSteps PRIMARY KEY (RowId) -); diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.003-25.004.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.003-25.004.sql deleted file mode 100644 index fdafb6463c9..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.003-25.004.sql +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- Switch to always store the lower case version of the path. First, ensure we only have one row per path, regardless --- of its casing -DELETE FROM core.ContainerAliases -WHERE Path NOT IN (SELECT MIN(Path) - FROM core.ContainerAliases - GROUP BY LOWER(Path)); - -UPDATE core.ContainerAliases SET Path = LOWER(Path); - --- Switch to using RowId as the FK to core.containers -ALTER TABLE core.ContainerAliases - ADD ContainerRowId INT; -GO - -UPDATE core.ContainerAliases -SET ContainerRowId = (SELECT RowId - FROM core.containers - WHERE core.containers.EntityId = core.ContainerAliases.ContainerId); - -ALTER TABLE core.ContainerAliases - DROP CONSTRAINT FK_ContainerAliases_Containers; -GO - -ALTER TABLE core.ContainerAliases - DROP COLUMN ContainerId; - -ALTER TABLE core.ContainerAliases - ADD CONSTRAINT FK_ContainerRowId FOREIGN KEY (ContainerRowId) - REFERENCES core.containers (RowId); - -CREATE INDEX idx_ContainerAliases_ContainerRowId ON core.ContainerAliases (ContainerRowId); \ No newline at end of file diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.004-25.005.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.004-25.005.sql deleted file mode 100644 index 60943237790..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.004-25.005.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- No longer used. See Issue 51520. -ALTER TABLE core.Logins DROP COLUMN Email; diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.005-25.006.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.005-25.006.sql deleted file mode 100644 index 4d3ead2ee1e..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.005-25.006.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- This index overlaps with uq_documents_parent_documentname -DROP INDEX ix_documents_parent ON core.Documents; diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.006-25.007.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.006-25.007.sql deleted file mode 100644 index 72b522b035d..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.006-25.007.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -DELETE FROM core.Members WHERE GroupId NOT IN (SELECT UserId FROM core.Principals WHERE Type IN ('g', 'm')); -ALTER TABLE core.Members ADD CONSTRAINT FK_Members_Principals FOREIGN KEY (GroupId) REFERENCES core.Principals (UserId); -CREATE INDEX IX_Members_GroupId ON core.Members(GroupId); diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.007-25.008.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.007-25.008.sql deleted file mode 100644 index 42454c4104b..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.007-25.008.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -ALTER TABLE core.Report ALTER COLUMN DescriptorXML NVARCHAR(MAX); \ No newline at end of file diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql deleted file mode 100644 index 3a1f0fc6410..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.008-25.009.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -ALTER TABLE core.Documents ADD ParentType NVARCHAR(300); diff --git a/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql b/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql deleted file mode 100644 index f5d3790e71d..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-25.009-25.010.sql +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- In 2019, we added support for multiple authentication configurations per provider and, at that time, attached --- authentication logos to each configuration. This deletes any old, orphaned, one-per-provider authentication logos --- that were attached directly to the root container. -DELETE FROM core.Documents WHERE - Container = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND - Parent = (SELECT EntityId FROM core.Containers WHERE Parent IS NULL) AND - ParentType IS NULL AND -- ParentType is always NULL at this point, since populating the column is deferred. But the DocumentName condition below is sufficiently specific. - (DocumentName LIKE 'auth_header_logo_%' OR DocumentName LIKE 'auth_login_page_logo_%'); diff --git a/core/resources/schemas/dbscripts/sqlserver/core-26.003-26.004.sql b/core/resources/schemas/dbscripts/sqlserver/core-26.003-26.004.sql deleted file mode 100644 index 5ef6fab5fde..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-26.003-26.004.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- Detection of the data class Compound.Structure2D attachment column was corrected in a recent PR: https://github.com/LabKey/platform/pull/7513 --- This re-populates the ParentType column to pick up those changes. -EXEC core.executeJavaUpgradeCode 'populateAttachmentParentTypeColumn'; diff --git a/core/resources/schemas/dbscripts/sqlserver/core-26.004-26.005.sql b/core/resources/schemas/dbscripts/sqlserver/core-26.004-26.005.sql deleted file mode 100644 index e43df61a0d7..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-26.004-26.005.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- Migrate login attempt settings from the compliance module's property store to core authentication settings. -EXEC core.executeJavaUpgradeCode 'migrateLoginAttemptSettings'; diff --git a/core/resources/schemas/dbscripts/sqlserver/core-26.006-26.007.sql b/core/resources/schemas/dbscripts/sqlserver/core-26.006-26.007.sql deleted file mode 100644 index 1e2671c861b..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-26.006-26.007.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE core.ApiKeys ADD RestrictionRole NVARCHAR(256); \ No newline at end of file diff --git a/core/resources/schemas/dbscripts/sqlserver/core-create.sql b/core/resources/schemas/dbscripts/sqlserver/core-create.sql deleted file mode 100644 index 0f948489e56..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-create.sql +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -CREATE VIEW core.Users AS - SELECT p.Name AS Email, ud.*, p.Active, CAST(CASE WHEN l.UserId IS NULL THEN 0 ELSE 1 END AS BIT) AS HasPassword - FROM core.Principals p - INNER JOIN core.UsersData ud ON p.UserId = ud.UserId - LEFT OUTER JOIN core.Logins l ON p.UserId = l.UserId - WHERE Type = 'u'; - -GO - -CREATE VIEW core.ActiveUsers AS - SELECT * - FROM core.Users - WHERE Active=1; - -GO - diff --git a/core/resources/schemas/dbscripts/sqlserver/core-drop.sql b/core/resources/schemas/dbscripts/sqlserver/core-drop.sql deleted file mode 100644 index b8436137d80..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/core-drop.sql +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -DROP VIEW IF EXISTS core.ActiveUsers; -DROP VIEW IF EXISTS core.Users; diff --git a/core/resources/schemas/dbscripts/sqlserver/enable_clr.sql b/core/resources/schemas/dbscripts/sqlserver/enable_clr.sql deleted file mode 100644 index 7e02aed7c83..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/enable_clr.sql +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2019-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -------------------------------------------------------------------------------------------------------------------------------- --- Turn advanced options on -EXEC sys.sp_configure @configname = 'show advanced options', @configvalue = 1 ; -GO -RECONFIGURE WITH OVERRIDE ; -GO --- Enable CLR -EXEC sys.sp_configure @configname = 'clr enabled', @configvalue = 1 ; -GO -RECONFIGURE WITH OVERRIDE ; -GO diff --git a/core/resources/schemas/dbscripts/sqlserver/group_concat_install.sql b/core/resources/schemas/dbscripts/sqlserver/group_concat_install.sql deleted file mode 100644 index 0d358297d29..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/group_concat_install.sql +++ /dev/null @@ -1,200 +0,0 @@ -/* - Copyright (c) 2011-2012 opcthree - - SQL Server GROUP_CONCAT CLR functions developed by "opcthree" based on UDA sample code in "Microsoft SQL Server - Books Online for SQL Server 2008 R2". Code is published at http://groupconcat.codeplex.com/ and licensed under the - Microsoft Public License (Ms-PL), included below per terms of the license: - - Microsoft Public License (Ms-PL) - - This license governs use of the accompanying software. If you use the software, you accept this license. If you do - not accept the license, do not use the software. - - 1. Definitions - - The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under - U.S. copyright law. - - A "contribution" is the original software, or any additions or changes to the software. - - A "contributor" is any person that distributes its contribution under this license. - - "Licensed patents" are a contributor's patent claims that read directly on its contribution. - - 2. Grant of Rights - - (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in - section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its - contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works - that you create. - - (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section - 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, - have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or - derivative works of the contribution in the software. - - 3. Conditions and Limitations - - (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. - - (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, - your patent license from such contributor to the software ends automatically. - - (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution - notices that are present in the software. - - (D) If you distribute any portion of the software in source code form, you may do so only under this license by - including a complete copy of this license with your distribution. If you distribute any portion of the software in - compiled or object code form, you may only do so under a license that complies with this license. - - (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, - guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot - change. To the extent permitted under your local laws, the contributors exclude the implied warranties of - merchantability, fitness for a particular purpose and non-infringement. - - Installation script for GROUP_CONCAT functions. Tested in SSMS 2008R2. - - This script installs GROUP_CONCAT SQL Server CLR 1.00.11845 (Beta) -*/ -SET NOCOUNT ON ; -GO - -------------------------------------------------------------------------------------------------------------------------------- --- Turn advanced options on -EXEC sys.sp_configure @configname = 'show advanced options', @configvalue = 1 ; -GO -RECONFIGURE WITH OVERRIDE ; -GO --- Enable CLR -EXEC sys.sp_configure @configname = 'clr enabled', @configvalue = 1 ; -GO -RECONFIGURE WITH OVERRIDE ; -GO -------------------------------------------------------------------------------------------------------------------------------- -SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, QUOTED_IDENTIFIER ON; -SET CONCAT_NULL_YIELDS_NULL, NUMERIC_ROUNDABORT OFF; -GO -IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE id=OBJECT_ID('tempdb..#tmpErrors')) DROP TABLE #tmpErrors -GO -CREATE TABLE #tmpErrors (Error int) -GO -SET XACT_ABORT ON -GO -SET TRANSACTION ISOLATION LEVEL READ COMMITTED -GO -BEGIN TRANSACTION -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating [GroupConcat]...'; -GO -CREATE ASSEMBLY [GroupConcat] - AUTHORIZATION [dbo] - FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C0103002454634F0000000000000000E00002210B010800001E00000008000000000000DE3C0000002000000040000000004000002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000843C000057000000004000003804000000000000000000000000000000000000006000000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000E41C000000200000001E000000020000000000000000000000000000200000602E7273726300000038040000004000000006000000200000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000002600000000000000000000000000004000004200000000000000000000000000000000C03C0000000000004800000002000500382C00004C10000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002204036F0E00000A2A1E02280F00000A2A0000001330020024000000010000110F01FE16060000016F1300000A0A027B0200000406281400000A2C0702067D020000042A5E02731500000A7D01000004027E1600000A7D020000042A133004004F000000020000110F01281700000A2D450F01281800000A0A027B01000004066F1900000A2C1B027B01000004250B06250C07086F1A00000A17586F1B00000A2B0D027B0100000406176F1C00000A020428030000062A001B3005007D000000030000110F017B010000046F1D00000A0C2B541202281E00000A0A1200281F00000A0B027B01000004076F1900000A2C29027B01000004250D072513040911046F1A00000A0F017B01000004076F1A00000A586F1B00000A2B0D027B0100000407176F1C00000A1202282000000A2DA3DE0E1202FE160300001B6F2100000ADC2A0000000110000002000D00616E000E000000001B300300B300000004000011027B0100000439A1000000027B010000046F2200000A163E90000000732300000A0A027B010000046F1D00000A0D2B351203281E00000A0B160C2B1F061201281F00000A6F2400000A2606027B020000046F2400000A260817580C081201282500000A32D71203282000000A2DC2DE0E1203FE160300001B6F2100000ADC06066F2600000A027B020000046F2700000A59027B020000046F2700000A6F2800000A6F1300000A282900000A2A14282900000A2A000110000002002E004270000E00000000133003004500000005000011036F2A00000A0A0206732B00000A7D01000004160B2B1B027B01000004036F2C00000A036F2A00000A6F1C00000A0717580B0706175931DF02036F2C00000A7D020000042A0000001B300200670000000600001103027B010000046F2200000A6F2D00000A027B010000046F1D00000A0B2B221201281E00000A0A031200281F00000A6F2E00000A031200282500000A6F2D00000A1201282000000A2DD5DE0E1201FE160300001B6F2100000ADC03027B020000046F2E00000A2A000110000002001D002F4C000E00000000EA027B040000042D310F01282F00000A172E150F01282F00000A182E0B7201000070733000000A7A020F01282F00000A283100000A7D040000042A4E02731500000A7D0300000402167D040000042A00133004004F000000020000110F01281700000A2D450F01281800000A0A027B03000004066F1900000A2C1B027B03000004250B06250C07086F1A00000A17586F1B00000A2B0D027B0300000406176F1C00000A0204280A0000062A001B3005007D000000030000110F017B030000046F1D00000A0C2B541202281E00000A0A1200281F00000A0B027B03000004076F1900000A2C29027B03000004250D072513040911046F1A00000A0F017B03000004076F1A00000A586F1B00000A2B0D027B0300000407176F1C00000A1202282000000A2DA3DE0E1202FE160300001B6F2100000ADC2A0000000110000002000D00616E000E000000001B300300C800000007000011027B0300000439B6000000027B030000046F2200000A163EA5000000732300000A0B027B04000004183313027B030000047302000006733200000A0A2B0C027B03000004733300000A0A066F3400000A13052B3A1205283500000A0C1202281F00000A0D1613042B1A07096F2400000A260772670000706F2400000A2611041758130411041202282500000A32DB1205283600000A2DBDDE0E1205FE160600001B6F2100000ADC07076F2600000A1759176F2800000A6F1300000A282900000A2A14282900000A2A01100000020052004799000E00000000133003004500000005000011036F2A00000A0A0206732B00000A7D03000004160B2B1B027B03000004036F2C00000A036F2A00000A6F1C00000A0717580B0706175931DF02036F3700000A7D040000042A0000001B300200670000000600001103027B030000046F2200000A6F2D00000A027B030000046F1D00000A0B2B221201281E00000A0A031200281F00000A6F2E00000A031200282500000A6F2D00000A1201282000000A2DD5DE0E1201FE160300001B6F2100000ADC03027B040000046F3800000A2A000110000002001D002F4C000E000000001330020024000000010000110F01FE16060000016F1300000A0A027B0600000406281400000A2C0702067D060000042AEA027B070000042D310F01282F00000A172E150F01282F00000A182E0B7201000070733000000A7A020F01282F00000A283100000A7D070000042A7A02731500000A7D05000004027E1600000A7D0600000402167D070000042A00001330040056000000020000110F01281700000A2D4C0F01281800000A0A027B05000004066F1900000A2C1B027B05000004250B06250C07086F1A00000A17586F1B00000A2B0D027B0500000406176F1C00000A02042811000006020528120000062A00001B3005007D000000030000110F017B050000046F1D00000A0C2B541202281E00000A0A1200281F00000A0B027B05000004076F1900000A2C29027B05000004250D072513040911046F1A00000A0F017B05000004076F1A00000A586F1B00000A2B0D027B0500000407176F1C00000A1202282000000A2DA3DE0E1202FE160300001B6F2100000ADC2A0000000110000002000D00616E000E000000001B300300D700000008000011027B0500000439C5000000027B050000046F2200000A163EB4000000732300000A0B027B07000004183313027B050000047302000006733200000A0A2B0C027B05000004733300000A0A066F3400000A13042B351204283500000A0C160D2B1F071202281F00000A6F2400000A2607027B060000046F2400000A260917580D091202282500000A32D71204283600000A2DC2DE0E1204FE160600001B6F2100000ADC07076F2600000A027B060000046F2700000A59027B060000046F2700000A6F2800000A6F1300000A282900000A2A14282900000A2A0001100000020052004294000E00000000133003005100000005000011036F2A00000A0A0206732B00000A7D05000004160B2B1B027B05000004036F2C00000A036F2A00000A6F1C00000A0717580B0706175931DF02036F2C00000A7D0600000402036F3700000A7D070000042A0000001B300200730000000600001103027B050000046F2200000A6F2D00000A027B050000046F1D00000A0B2B221201281E00000A0A031200281F00000A6F2E00000A031200282500000A6F2D00000A1201282000000A2DD5DE0E1201FE160300001B6F2100000ADC03027B060000046F2E00000A03027B070000046F3800000A2A000110000002001D002F4C000E000000003202731500000A7D080000042A0000001330040047000000020000110F01281700000A2D3D0F01281800000A0A027B08000004066F1900000A2C1A027B08000004250B06250C07086F1A00000A17586F1B00000A2A027B0800000406176F1C00000A2A001B3005007D000000030000110F017B080000046F1D00000A0C2B541202281E00000A0A1200281F00000A0B027B08000004076F1900000A2C29027B08000004250D072513040911046F1A00000A0F017B08000004076F1A00000A586F1B00000A2B0D027B0800000407176F1C00000A1202282000000A2DA3DE0E1202FE160300001B6F2100000ADC2A0000000110000002000D00616E000E000000001B3003009B00000004000011027B080000043989000000027B080000046F2200000A16317B732300000A0A027B080000046F1D00000A0D2B341203281E00000A0B160C2B1E061201281F00000A6F2400000A260672670000706F2400000A260817580C081201282500000A32D81203282000000A2DC3DE0E1203FE160300001B6F2100000ADC06066F2600000A1759176F2800000A6F1300000A282900000A2A14282900000A2A000110000002002B00416C000E00000000133003003900000005000011036F2A00000A0A0206732B00000A7D08000004160B2B1B027B08000004036F2C00000A036F2A00000A6F1C00000A0717580B0706175931DF2A0000001B3002005B0000000600001103027B080000046F2200000A6F2D00000A027B080000046F1D00000A0B2B221201281E00000A0A031200281F00000A6F2E00000A031200282500000A6F2D00000A1201282000000A2DD5DE0E1201FE160300001B6F2100000ADC2A000110000002001D002F4C000E0000000042534A4201000100000000000C00000076322E302E35303732370000000005006C000000BC060000237E0000280700005405000023537472696E6773000000007C0C00006C00000023555300E80C0000100000002347554944000000F80C00005403000023426C6F6200000000000000020000015717A2090900000000FA253300160000010000002500000006000000080000001E0000001E0000000500000038000000180000000800000003000000040000000400000006000000010000000300000000000A00010000000000060081007A000600A30088000600AF007A000A00E000C5000600FF0088000A0032011D01060074016A01060086016A010A00AA011D010A00D401C50006001702050206002E02050206004B02050206006A02050206008302050206009C0205020600B70205020600D202050206000A03EB0206001E030502060057033703060077033703060095037A000600A6037A000A00BC03C5000A00DD03C5000600E403EB020600FA03EB0217005904000006007204880006009E047A000600C804BC04060010057A0006001A057A000E002905880006003C0588008F00590400000000000001000000000001000100010010001A002A000500010001000921100036002A000D00010003000921100045002A000D0003000A000921100054002A000D00050011000921100064002A000D000800190001000C011A0001001301220001000C011A000100A3014F0001000C011A000100130122000100A3014F0001000C011A00502000000000E601F100100001005920000000008618F9001600030064200000000081083C012500030094200000000086004A0116000400AC200000000086004F012B00040008210000000086005A0133000600A421000000008600600139000700742200000000E60181013E000800C82200000000E6019301440009004C23000000008108B20152000A0087230000000086004A0116000B009C230000000086004F0158000B00F8230000000086005A0160000D009424000000008600600139000E00782500000000E60181013E000F00CC2500000000E60193014400100050260000000081083C01250011008026000000008108B20152001200BB260000000086004A0116001300DC260000000086004F016B00130040270000000086005A0175001600DC27000000008600600139001700D02800000000E60181013E001800302900000000E601930144001900C0290000000086004A0116001A00D0290000000086004F0125001A00242A0000000086005A017B001B00C02A000000008600600139001C00782B00000000E60181013E001D00C02B00000000E601930144001E0000000100C40100000200C60100000100C80100000100CE0100000200E60100000100F00100000000000000000100F60100000100F80100000100C80100000100CE0100000200FA0100000100F00100000000000000000100F60100000100F80100000100C80100000100C80100000100CE0100000200E60100000300FA0100000100F00100000000000000000100F60100000100F80100000100CE0100000100F00100000000000000000100F60100000100F80102000600030011000400110005001100060011005100F90016005900F900BA006100F900BA006900F900BA007100F900BA007900F900BA008100F900BA008900F900BA009100F900BA009900F900BF00A100F900BA00A900F900C400B100F9001600B9009C03C9000900F9001600C100F9001600C900F900CE00D900F9004701090005044D01B9000E0451011400F9001600B9001C04220031002204620131002D044D01140037046601140043046C0114004C0473011400550473011400640486011C008104980124008D04AA011C0095046201F900AA0416001400B204C6010101F90016000101D604CA0124002D04D1010101DD04C601B900DD04C6010101E804D6013100EF04DE013900FB04C6011400F900C400390005054D0141009301C40041009301BA0049002D040B020901F900BA00110122050F022C00F9001C022C00F9002F022C0064043C0234008104980134009504620139004A050B02410093016C022E006B0035032E002B000E032E0013008C022E001B009D022E0023000E032E003B0014032E0033008C022E0043000E032E0053000E032E0063002C0363008B00D40083008B00D40084000B008100A3008B00D400A4000B009400C3008B00D400E4000B00A70064010B008100C4010B00A70064020B00810084020B009400E4020B00A70044030B00810084030B00A70057017B01AF01E401F701FC0150027102030001000400020005000300000099014A000000BD016600000099014A000000BD01660001000300030001000A0005000100110007000100120009000A005B019101A3011402480204800000010000006A119A370000000000002A00000002000000000000000000000001007100000000000200000000000000000000000100B9000000000002000000000000000000000001007A00000000000000003C4D6F64756C653E0047726F7570436F6E6361742E646C6C0052657665727365436F6D70617265720047726F7570436F6E6361740047524F55505F434F4E4341545F440047524F55505F434F4E4341545F530047524F55505F434F4E4341545F44530047524F55505F434F4E434154006D73636F726C69620053797374656D004F626A6563740053797374656D2E436F6C6C656374696F6E732E47656E657269630049436F6D706172657260310056616C7565547970650053797374656D2E44617461004D6963726F736F66742E53716C5365727665722E536572766572004942696E61727953657269616C697A6500436F6D70617265002E63746F720044696374696F6E61727960320076616C7565730064656C696D697465720053797374656D2E446174612E53716C54797065730053716C537472696E67007365745F44656C696D6974657200496E697400416363756D756C617465004D65726765005465726D696E6174650053797374656D2E494F0042696E61727952656164657200526561640042696E6172795772697465720057726974650044656C696D6974657200736F727442790053716C42797465007365745F536F7274427900536F72744279007800790076616C75650056414C55450053716C46616365744174747269627574650044454C494D495445520047726F75700072007700534F52545F4F524445520053797374656D2E5265666C656374696F6E00417373656D626C795469746C6541747472696275746500417373656D626C794465736372697074696F6E41747472696275746500417373656D626C79436F6E66696775726174696F6E41747472696275746500417373656D626C79436F6D70616E7941747472696275746500417373656D626C7950726F6475637441747472696275746500417373656D626C79436F7079726967687441747472696275746500417373656D626C7954726164656D61726B41747472696275746500417373656D626C7943756C747572654174747269627574650053797374656D2E52756E74696D652E496E7465726F70536572766963657300436F6D56697369626C6541747472696275746500417373656D626C7956657273696F6E4174747269627574650053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C69747941747472696275746500537472696E6700436F6D70617265546F0053657269616C697A61626C654174747269627574650053716C55736572446566696E656441676772656761746541747472696275746500466F726D6174005374727563744C61796F7574417474726962757465004C61796F75744B696E6400546F537472696E67006F705F496E657175616C69747900456D707479006765745F49734E756C6C006765745F56616C756500436F6E7461696E734B6579006765745F4974656D007365745F4974656D0041646400456E756D657261746F7200476574456E756D657261746F72004B657956616C7565506169726032006765745F43757272656E74006765745F4B6579004D6F76654E6578740049446973706F7361626C6500446973706F7365006765745F436F756E740053797374656D2E5465787400537472696E674275696C64657200417070656E64006765745F4C656E6774680052656D6F7665006F705F496D706C696369740052656164496E7433320052656164537472696E6700457863657074696F6E00436F6E7665727400546F4279746500536F7274656444696374696F6E6172796032004944696374696F6E61727960320052656164427974650000006549006E00760061006C0069006400200053006F0072007400420079002000760061006C00750065003A00200075007300650020003100200066006F007200200041005300430020006F00720020003200200066006F007200200044004500530043002E0000032C0000003D06AA77BA3EE241AA3E6C354E99AFF20008B77A5C561934E08905151209010E052002080E0E032000010706151215020E0802060E052001011119072002011119111905200101110C042000111905200101121D0520010112210428001119020605052001011125072002011119112505200101111004280011250920030111191119112505200101111405200101111812010001005408074D617853697A65A00F000012010001005408074D617853697A650400000012010001005408074D617853697A65FFFFFFFF042001010E04200101020420010108042001080E05200101116972010002000000050054080B4D61784279746553697A65FFFFFFFF5402124973496E76617269616E74546F4E756C6C73015402174973496E76617269616E74546F4475706C696361746573005402124973496E76617269616E74546F4F726465720154020D49734E756C6C4966456D707479010520010111710320000E050002020E0E0307010E06151215020E08032000020520010213000620011301130007200201130013010A07030E151215020E080E0A2000151175021300130106151175020E080A2000151179021300130106151179020E080420001300160705151179020E080E151175020E08151215020E080E032000080620011280810E0420001301072002128081080805000111190E120704128081151179020E0808151175020E0804070208080E0702151179020E08151175020E08032000050400010505071512808D020E08122002011512809102130013011512090113000C2001011512809102130013010B20001511809502130013010715118095020E081B07061512808D020E08128081151179020E080E0815118095020E0804200101051A07051512808D020E08128081151179020E080815118095020E081001000B47726F7570436F6E63617400007001006B537472696E6720636F6E636174656E6174696F6E2061676772656761746520666F722053514C205365727665722E2044726F702D696E207265706C6163656D656E7420666F72206275696C742D696E204D7953514C2047524F55505F434F4E4341542066756E74696F6E2E000005010000000017010012436F7079726967687420C2A920203230313100000801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F777301AC3C00000000000000000000CE3C0000002000000000000000000000000000000000000000000000C03C00000000000000000000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF2500204000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000001800008000000000000000000000000000000100010000003000008000000000000000000000000000000100000000004800000058400000E00300000000000000000000E00334000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE00000100000001009A376A11000001009A376A113F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B00440030000010053007400720069006E006700460069006C00650049006E0066006F0000001C0300000100300030003000300030003400620030000000F0006C00010043006F006D006D0065006E0074007300000053007400720069006E006700200063006F006E0063006100740065006E006100740069006F006E002000610067006700720065006700610074006500200066006F0072002000530051004C0020005300650072007600650072002E002000440072006F0070002D0069006E0020007200650070006C006100630065006D0065006E007400200066006F00720020006200750069006C0074002D0069006E0020004D007900530051004C002000470052004F00550050005F0043004F004E004300410054002000660075006E00740069006F006E002E00000040000C000100460069006C0065004400650073006300720069007000740069006F006E0000000000470072006F007500700043006F006E00630061007400000040000F000100460069006C006500560065007200730069006F006E000000000031002E0030002E0034003400350038002E00310034003200330034000000000040001000010049006E007400650072006E0061006C004E0061006D0065000000470072006F007500700043006F006E006300610074002E0064006C006C0000004800120001004C006500670061006C0043006F007000790072006900670068007400000043006F0070007900720069006700680074002000A90020002000320030003100310000004800100001004F0072006900670069006E0061006C00460069006C0065006E0061006D0065000000470072006F007500700043006F006E006300610074002E0064006C006C00000038000C000100500072006F0064007500630074004E0061006D00650000000000470072006F007500700043006F006E00630061007400000044000F000100500072006F006400750063007400560065007200730069006F006E00000031002E0030002E0034003400350038002E00310034003200330034000000000048000F00010041007300730065006D0062006C0079002000560065007200730069006F006E00000031002E0030002E0034003400350038002E003100340032003300340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000C000000E03C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - WITH PERMISSION_SET = SAFE; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -EXEC sys.sp_addextendedproperty - @name = N'URL', - @value = N'http://groupconcat.codeplex.com', - @level0type = N'ASSEMBLY', - @level0name = N'GroupConcat' -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating core.[GROUP_CONCAT_D]...'; -GO -CREATE AGGREGATE core.[GROUP_CONCAT_D](@VALUE NVARCHAR (4000), @DELIMITER NVARCHAR (4)) - RETURNS NVARCHAR (MAX) - EXTERNAL NAME [GroupConcat].[GroupConcat.GROUP_CONCAT_D]; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating core.[GROUP_CONCAT_S]...'; -GO -CREATE AGGREGATE core.[GROUP_CONCAT_S](@VALUE NVARCHAR (4000), @SORT_ORDER TINYINT) - RETURNS NVARCHAR (MAX) - EXTERNAL NAME [GroupConcat].[GroupConcat.GROUP_CONCAT_S]; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating core.[GROUP_CONCAT_DS]...'; -GO -CREATE AGGREGATE core.[GROUP_CONCAT_DS](@VALUE NVARCHAR (4000), @DELIMITER NVARCHAR (4), @SORT_ORDER TINYINT) - RETURNS NVARCHAR (MAX) - EXTERNAL NAME [GroupConcat].[GroupConcat.GROUP_CONCAT_DS]; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating core.[GROUP_CONCAT]...'; -GO -CREATE AGGREGATE core.[GROUP_CONCAT](@VALUE NVARCHAR (4000)) - RETURNS NVARCHAR (MAX) - EXTERNAL NAME [GroupConcat].[GroupConcat.GROUP_CONCAT]; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -------------------------------------------------------------------------------------------------------------------- -IF EXISTS (SELECT * FROM #tmpErrors) ROLLBACK TRANSACTION -GO -IF @@TRANCOUNT>0 BEGIN -PRINT N'The transacted portion of the database update succeeded.' -COMMIT TRANSACTION -END -ELSE PRINT N'The transacted portion of the database update failed.' -GO -DROP TABLE #tmpErrors -------------------------------------------------------------------------------------------------------------------- -GO diff --git a/core/resources/schemas/dbscripts/sqlserver/group_concat_install_1.00.23696.sql b/core/resources/schemas/dbscripts/sqlserver/group_concat_install_1.00.23696.sql deleted file mode 100644 index 2ddd531b850..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/group_concat_install_1.00.23696.sql +++ /dev/null @@ -1,220 +0,0 @@ -/* - - This script installs GROUP_CONCAT SQL Server CLR 1.00.23696 (Beta) - - Copyright (c) 2011-2013 opcthree - - SQL Server GROUP_CONCAT CLR functions developed by "opcthree" based on UDA sample code in "Microsoft SQL Server - Books Online for SQL Server 2008 R2". Code is published at http://groupconcat.codeplex.com/ and licensed under the - Microsoft Public License (Ms-PL), included below per terms of the license: - - Microsoft Public License (Ms-PL) - - This license governs use of the accompanying software. If you use the software, you accept this license. If you do - not accept the license, do not use the software. - - 1. Definitions - - The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under - U.S. copyright law. - - A "contribution" is the original software, or any additions or changes to the software. - - A "contributor" is any person that distributes its contribution under this license. - - "Licensed patents" are a contributor's patent claims that read directly on its contribution. - - 2. Grant of Rights - - (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in - section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its - contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works - that you create. - - (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section - 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, - have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or - derivative works of the contribution in the software. - - 3. Conditions and Limitations - - (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. - - (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, - your patent license from such contributor to the software ends automatically. - - (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution - notices that are present in the software. - - (D) If you distribute any portion of the software in source code form, you may do so only under this license by - including a complete copy of this license with your distribution. If you distribute any portion of the software in - compiled or object code form, you may only do so under a license that complies with this license. - - (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, - guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot - change. To the extent permitted under your local laws, the contributors exclude the implied warranties of - merchantability, fitness for a particular purpose and non-infringement. - - */ - -SET NOCOUNT ON ; -GO - -@@ENABLE_CLR_STATEMENTS@@ --- Add trusted assembly if we are running on SQLServer 2017 -IF OBJECT_ID(N'sys.trusted_assemblies', N'V') IS NOT NULL -BEGIN - DECLARE @hash VARBINARY(64) = 0x0240D1FD09DBD2398E310A16C7628D1F8F2DB0EC0AFDC0C0617AB49B9480F4B479B1CCAF469B969B53E924922052E7750DD54A4A79F3366979FB7BD617B57ED6; - DECLARE @description NVARCHAR(4000) = N'groupconcat, version=0.0.0.0, culture=neutral, publickeytoken=null, processorarchitecture=msil'; - - IF NOT EXISTS (SELECT * FROM sys.trusted_assemblies WHERE hash = @hash) - EXEC sys.sp_add_trusted_assembly @hash, @description - -END -GO - - -------------------------------------------------------------------------------------------------------------------------------- -SET ANSI_NULLS, ANSI_PADDING, ANSI_WARNINGS, ARITHABORT, QUOTED_IDENTIFIER ON; -SET CONCAT_NULL_YIELDS_NULL, NUMERIC_ROUNDABORT OFF; -GO -IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE id=OBJECT_ID('tempdb..#tmpErrors')) DROP TABLE #tmpErrors -GO -CREATE TABLE #tmpErrors (Error int) -GO -SET XACT_ABORT ON -GO -SET TRANSACTION ISOLATION LEVEL READ COMMITTED -GO -BEGIN TRANSACTION -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating [GroupConcat]...'; -GO -CREATE ASSEMBLY [GroupConcat] - AUTHORIZATION [dbo] - FROM 0x4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000504500004C01030058898C510000000000000000E00002210B010B00001E000000080000000000007E3D0000002000000040000000000010002000000002000004000000000000000400000000000000008000000002000000000000030040850000100000100000000010000010000000000000100000000000000000000000243D000057000000004000003804000000000000000000000000000000000000006000000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000082000004800000000000000000000002E74657874000000841D000000200000001E000000020000000000000000000000000000200000602E7273726300000038040000004000000006000000200000000000000000000000000000400000402E72656C6F6300000C0000000060000000020000002600000000000000000000000000004000004200000000000000000000000000000000603D0000000000004800000002000500C02C00006410000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003202731100000A7D010000042A0000001330040047000000010000110F01281200000A2D3D0F01281300000A0A027B01000004066F1400000A2C1A027B01000004250B06250C07086F1500000A17586F1600000A2A027B0100000406176F1700000A2A001B30050089000000020000110F017B010000046F1800000A0C2B601202281900000A0A1200281A00000A0B027B01000004076F1400000A2C29027B01000004250D072513040911046F1500000A0F017B01000004076F1500000A586F1600000A2B19027B01000004070F017B01000004076F1500000A6F1700000A1202281B00000A2D97DE0E1202FE160300001B6F1C00000ADC2A0000000110000002000D006D7A000E000000001B3003009B00000003000011027B010000043989000000027B010000046F1D00000A16317B731E00000A0A027B010000046F1800000A0D2B341203281900000A0B160C2B1E061201281A00000A6F1F00000A260672010000706F1F00000A260817580C081201282000000A32D81203281B00000A2DC3DE0E1203FE160300001B6F1C00000ADC06066F2100000A1759176F2200000A6F2300000A282400000A2A14282400000A2A000110000002002B00416C000E00000000133003003900000004000011036F2500000A0A0206732600000A7D01000004160B2B1B027B01000004036F2700000A036F2500000A6F1700000A0717580B0706175931DF2A0000001B3002005B0000000500001103027B010000046F1D00000A6F2800000A027B010000046F1800000A0B2B221201281900000A0A031200281A00000A6F2900000A031200282000000A6F2800000A1201281B00000A2DD5DE0E1201FE160300001B6F1C00000ADC2A000110000002001D002F4C000E000000001330020024000000060000110F01FE16060000016F2300000A0A027B0300000406282A00000A2C0702067D030000042A5E02731100000A7D02000004027E2B00000A7D030000042A133004004F000000010000110F01281200000A2D450F01281300000A0A027B02000004066F1400000A2C1B027B02000004250B06250C07086F1500000A17586F1600000A2B0D027B0200000406176F1700000A020428070000062A001B300500A300000002000011027B03000004282C00000A2C0D020F017B030000047D030000040F017B020000046F1800000A0C2B601202281900000A0A1200281A00000A0B027B02000004076F1400000A2C29027B02000004250D072513040911046F1500000A0F017B02000004076F1500000A586F1600000A2B19027B02000004070F017B02000004076F1500000A6F1700000A1202281B00000A2D97DE0E1202FE160300001B6F1C00000ADC2A0001100000020027006D94000E000000001B300300B300000003000011027B0200000439A1000000027B020000046F1D00000A163E90000000731E00000A0A027B020000046F1800000A0D2B351203281900000A0B160C2B1F061201281A00000A6F1F00000A2606027B030000046F1F00000A260817580C081201282000000A32D71203281B00000A2DC2DE0E1203FE160300001B6F1C00000ADC06066F2100000A027B030000046F2D00000A59027B030000046F2D00000A6F2200000A6F2300000A282400000A2A14282400000A2A000110000002002E004270000E00000000133003004500000004000011036F2500000A0A0206732600000A7D02000004160B2B1B027B02000004036F2700000A036F2500000A6F1700000A0717580B0706175931DF02036F2700000A7D030000042A0000001B300200670000000500001103027B020000046F1D00000A6F2800000A027B020000046F1800000A0B2B221201281900000A0A031200281A00000A6F2900000A031200282000000A6F2800000A1201281B00000A2DD5DE0E1201FE160300001B6F1C00000ADC03027B030000046F2900000A2A000110000002001D002F4C000E000000001330020024000000060000110F01FE16060000016F2300000A0A027B0500000406282A00000A2C0702067D050000042AEA027B060000042D310F01282E00000A172E150F01282E00000A182E0B7205000070732F00000A7A020F01282E00000A283000000A7D060000042A7A02731100000A7D04000004027E2B00000A7D0500000402167D060000042A00001330040056000000010000110F01281200000A2D4C0F01281300000A0A027B04000004066F1400000A2C1B027B04000004250B06250C07086F1500000A17586F1600000A2B0D027B0400000406176F1700000A0204280E0000060205280F0000062A00001B300500B800000002000011027B05000004282C00000A2C0D020F017B050000047D05000004027B060000042D0D020F017B060000047D060000040F017B040000046F1800000A0C2B601202281900000A0A1200281A00000A0B027B04000004076F1400000A2C29027B04000004250D072513040911046F1500000A0F017B04000004076F1500000A586F1600000A2B19027B04000004070F017B04000004076F1500000A6F1700000A1202281B00000A2D97DE0E1202FE160300001B6F1C00000ADC2A0110000002003C006DA9000E000000001B300300D700000007000011027B0400000439C5000000027B040000046F1D00000A163EB4000000731E00000A0B027B06000004183313027B04000004731E000006733100000A0A2B0C027B04000004733200000A0A066F3300000A13042B351204283400000A0C160D2B1F071202281A00000A6F1F00000A2607027B050000046F1F00000A260917580D091202282000000A32D71204283500000A2DC2DE0E1204FE160600001B6F1C00000ADC07076F2100000A027B050000046F2D00000A59027B050000046F2D00000A6F2200000A6F2300000A282400000A2A14282400000A2A0001100000020052004294000E00000000133003005100000004000011036F2500000A0A0206732600000A7D04000004160B2B1B027B04000004036F2700000A036F2500000A6F1700000A0717580B0706175931DF02036F2700000A7D0500000402036F3600000A7D060000042A0000001B300200730000000500001103027B040000046F1D00000A6F2800000A027B040000046F1800000A0B2B221201281900000A0A031200281A00000A6F2900000A031200282000000A6F2800000A1201281B00000A2DD5DE0E1201FE160300001B6F1C00000ADC03027B050000046F2900000A03027B060000046F3700000A2A000110000002001D002F4C000E00000000EA027B080000042D310F01282E00000A172E150F01282E00000A182E0B7205000070732F00000A7A020F01282E00000A283000000A7D080000042A4E02731100000A7D0700000402167D080000042A00133004004F000000010000110F01281200000A2D450F01281300000A0A027B07000004066F1400000A2C1B027B07000004250B06250C07086F1500000A17586F1600000A2B0D027B0700000406176F1700000A020428160000062A001B3005009E00000002000011027B080000042D0D020F017B080000047D080000040F017B070000046F1800000A0C2B601202281900000A0A1200281A00000A0B027B07000004076F1400000A2C29027B07000004250D072513040911046F1500000A0F017B07000004076F1500000A586F1600000A2B19027B07000004070F017B07000004076F1500000A6F1700000A1202281B00000A2D97DE0E1202FE160300001B6F1C00000ADC2A000001100000020022006D8F000E000000001B300300C800000008000011027B0700000439B6000000027B070000046F1D00000A163EA5000000731E00000A0B027B08000004183313027B07000004731E000006733100000A0A2B0C027B07000004733200000A0A066F3300000A13052B3A1205283400000A0C1202281A00000A0D1613042B1A07096F1F00000A260772010000706F1F00000A2611041758130411041202282000000A32DB1205283500000A2DBDDE0E1205FE160600001B6F1C00000ADC07076F2100000A1759176F2200000A6F2300000A282400000A2A14282400000A2A01100000020052004799000E00000000133003004500000004000011036F2500000A0A0206732600000A7D07000004160B2B1B027B07000004036F2700000A036F2500000A6F1700000A0717580B0706175931DF02036F3600000A7D080000042A0000001B300200670000000500001103027B070000046F1D00000A6F2800000A027B070000046F1800000A0B2B221201281900000A0A031200281A00000A6F2900000A031200282000000A6F2800000A1201281B00000A2DD5DE0E1201FE160300001B6F1C00000ADC03027B080000046F3700000A2A000110000002001D002F4C000E000000002204036F3800000A2A1E02283900000A2A00000042534A4201000100000000000C00000076322E302E35303732370000000005006C000000C4060000237E0000300700006405000023537472696E677300000000940C00006C00000023555300000D0000100000002347554944000000100D00005403000023426C6F6200000000000000020000015717A2090900000000FA253300160000010000002500000006000000080000001E0000001E0000000500000039000000180000000800000003000000040000000400000006000000010000000300000000000A00010000000000060081007A000A00B20097000600C3007A000600E500CA000600F100CA000A001F010A0106004E0144010600600144010A009C010A010A00CA01970006001702050206002E02050206004B02050206006A02050206008302050206009C0205020600B70205020600D202050206000A03EB0206001E030502060057033703060077033703060095037A000A00AB0397000A00CC0397000600D303EB020600E903EB0217002B04000006004404CA00060070047A0006009A048E040600EB047A00060014057A0006001E057A000E002D05CA0006004005CA008F002B0400000000000001000000000001000100092110001A00270005000100010009211000330027000500020007000921100042002700050004000E00092110005200270005000700160001001000610027000D0009001D000100FE0010000100FE0010000100730139000100FE001000010073013900010095014F000100FE001000010095014F005020000000008600050118000100602000000000860029011C000100B4200000000086003401220002005C210000000086003A0128000300142200000000E6015B012D0004005C2200000000E6016D0133000500D4220000000081087D011C00060004230000000086000501180007001C2300000000860029013C000700782300000000860034014400090038240000000086003A0128000A00082500000000E6015B012D000B005C2500000000E6016D0133000C00E0250000000081087D011C000D001026000000008108A40152000E004B26000000008600050118000F006C26000000008600290158000F00D026000000008600340162001200A4270000000086003A0128001300982800000000E6015B012D001400F82800000000E6016D01330015008829000000008108A40152001600C329000000008600050118001700D82900000000860029016D001700342A000000008600340175001900F02A0000000086003A0128001A00D42B00000000E6015B012D001B00282C00000000E6016D0133001C00AC2C00000000E601B6017B001D00B52C000000008618BE0118001F0000000100C40100000100DC0100000000000000000100E20100000100E40100000100E60100000100C40100000200EC0100000100DC0100000000000000000100E20100000100E40100000100E60100000100E60100000100C40100000200EC0100000300F60100000100DC0100000000000000000100E20100000100E40100000100E60100000100C40100000200F60100000100DC0100000000000000000100E20100000100E40100000100010200000200030202000900030009000400090005000900060006005100BE0118005900BE01BA006100BE01BA006900BE01BA007100BE01BA007900BE01BA008100BE01BA008900BE01BA009100BE01BA009900BE01BF00A100BE01BA00A900BE01C400B100BE011800B900BE011800C100BE01C900D100BE0142011400BE0118003100F4034F013100FF035301140009045701140015045D0114001E0464011400270464011400360477011C005304890124005F049B011C0067044F01F1007C04180014008404B701F900BE011800F900A804BB012400FF03C101F900AF04B701F900BA04C6011900C10453013100CA04CD013900D604B7011400BE01C4003900E004530141006D01C40041006D01BA000101F204F9010101000539000101060503020101AF04B7014900FF0308020901BE01BA00110126050C022C00BE0119022C00BE012C022C0036043902340053048901340067044F0139004E05080241006D0167020101570587021900BE01180024000B0081002E006B0035032E002B000E032E0013008C022E001B009D022E0023000E032E003B0014032E0033008C022E0043000E032E0053000E032E0063002C0343007B00CF0063007B00CF0064000B00940083007B00CF00A3007B00CF00E4000B00810004010B00A70044010B009400E4010B00810004020B00A70064020B009400E4020B00810044030B0094006C01A001D301E501EA01FF014D026C0203000100040002000500040000008B014A0000008B014A000000AF0168000000AF01680001000700030001000E00050001000F0007000100160009000A004801820194011102450204800000010000000D13F49F00000000000027000000020000000000000000000000010071000000000002000000000000000000000001008B000000000002000000000000000000000001007A000000000000000000003C4D6F64756C653E0047726F7570436F6E6361742E646C6C0047524F55505F434F4E4341540047726F7570436F6E6361740047524F55505F434F4E4341545F440047524F55505F434F4E4341545F44530047524F55505F434F4E4341545F530052657665727365436F6D7061726572006D73636F726C69620053797374656D0056616C7565547970650053797374656D2E44617461004D6963726F736F66742E53716C5365727665722E536572766572004942696E61727953657269616C697A65004F626A6563740053797374656D2E436F6C6C656374696F6E732E47656E657269630049436F6D706172657260310044696374696F6E61727960320076616C75657300496E69740053797374656D2E446174612E53716C54797065730053716C537472696E6700416363756D756C617465004D65726765005465726D696E6174650053797374656D2E494F0042696E61727952656164657200526561640042696E6172795772697465720057726974650064656C696D69746572007365745F44656C696D697465720044656C696D6974657200736F727442790053716C42797465007365745F536F7274427900536F7274427900436F6D70617265002E63746F720056414C55450053716C46616365744174747269627574650047726F7570007200770076616C75650044454C494D4954455200534F52545F4F52444552007800790053797374656D2E5265666C656374696F6E00417373656D626C795469746C6541747472696275746500417373656D626C794465736372697074696F6E41747472696275746500417373656D626C79436F6E66696775726174696F6E41747472696275746500417373656D626C79436F6D70616E7941747472696275746500417373656D626C7950726F6475637441747472696275746500417373656D626C79436F7079726967687441747472696275746500417373656D626C7954726164656D61726B41747472696275746500417373656D626C7943756C747572654174747269627574650053797374656D2E52756E74696D652E496E7465726F70536572766963657300436F6D56697369626C6541747472696275746500417373656D626C7956657273696F6E4174747269627574650053797374656D2E52756E74696D652E436F6D70696C6572536572766963657300436F6D70696C6174696F6E52656C61786174696F6E734174747269627574650052756E74696D65436F6D7061746962696C6974794174747269627574650053657269616C697A61626C654174747269627574650053716C55736572446566696E656441676772656761746541747472696275746500466F726D6174005374727563744C61796F7574417474726962757465004C61796F75744B696E64006765745F49734E756C6C006765745F56616C756500436F6E7461696E734B6579006765745F4974656D007365745F4974656D0041646400456E756D657261746F7200476574456E756D657261746F72004B657956616C7565506169726032006765745F43757272656E74006765745F4B6579004D6F76654E6578740049446973706F7361626C6500446973706F7365006765745F436F756E740053797374656D2E5465787400537472696E674275696C64657200417070656E64006765745F4C656E6774680052656D6F766500546F537472696E67006F705F496D706C696369740052656164496E7433320052656164537472696E6700537472696E67006F705F496E657175616C69747900456D7074790049734E756C6C4F72456D70747900457863657074696F6E00436F6E7665727400546F4279746500536F7274656444696374696F6E6172796032004944696374696F6E617279603200526561644279746500436F6D70617265546F0000000000032C00006549006E00760061006C0069006400200053006F0072007400420079002000760061006C00750065003A00200075007300650020003100200066006F007200200041005300430020006F00720020003200200066006F007200200044004500530043002E0000008002D97266C26949A672EA780F71C8980008B77A5C561934E08905151211010E0706151215020E0803200001052001011119052001011108042000111905200101121D05200101122102060E072002011119111905200101110C04280011190206050520010111250920030111191119112505200101111004280011250720020111191125052001011114052002080E0E12010001005408074D617853697A65A00F000012010001005408074D617853697A65FFFFFFFF12010001005408074D617853697A6504000000042001010E0420010102042001010805200101116572010002000000050054080B4D61784279746553697A65FFFFFFFF5402124973496E76617269616E74546F4E756C6C73015402174973496E76617269616E74546F4475706C696361746573005402124973496E76617269616E74546F4F726465720154020D49734E756C6C4966456D7074790105200101116D06151215020E08032000020320000E0520010213000620011301130007200201130013010A07030E151215020E080E0A2000151171021300130106151171020E080A2000151175021300130106151175020E080420001300160705151175020E080E151171020E08151215020E080E03200008052001127D0E0420001301062002127D080805000111190E110704127D151175020E0808151171020E0804070208080E0702151175020E08151171020E08050002020E0E0307010E040001020E032000050400010505071512808D020E08122002011512809102130013011512110113000C2001011512809102130013010B20001511809502130013010715118095020E081907051512808D020E08127D151175020E080815118095020E0804200101051A07061512808D020E08127D151175020E080E0815118095020E08042001080E1001000B47726F7570436F6E63617400007001006B537472696E6720636F6E636174656E6174696F6E2061676772656761746520666F722053514C205365727665722E2044726F702D696E207265706C6163656D656E7420666F72206275696C742D696E204D7953514C2047524F55505F434F4E4341542066756E74696F6E2E000005010000000017010012436F7079726967687420C2A920203230313100000801000800000000001E01000100540216577261704E6F6E457863657074696F6E5468726F7773014C3D000000000000000000006E3D0000002000000000000000000000000000000000000000000000603D00000000000000000000000000000000000000005F436F72446C6C4D61696E006D73636F7265652E646C6C0000000000FF25002000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100100000001800008000000000000000000000000000000100010000003000008000000000000000000000000000000100000000004800000058400000E00300000000000000000000E00334000000560053005F00560045005200530049004F004E005F0049004E0046004F0000000000BD04EFFE0000010000000100F49F0D1300000100F49F0D133F000000000000000400000002000000000000000000000000000000440000000100560061007200460069006C00650049006E0066006F00000000002400040000005400720061006E0073006C006100740069006F006E00000000000000B00440030000010053007400720069006E006700460069006C00650049006E0066006F0000001C0300000100300030003000300030003400620030000000F0006C00010043006F006D006D0065006E0074007300000053007400720069006E006700200063006F006E0063006100740065006E006100740069006F006E002000610067006700720065006700610074006500200066006F0072002000530051004C0020005300650072007600650072002E002000440072006F0070002D0069006E0020007200650070006C006100630065006D0065006E007400200066006F00720020006200750069006C0074002D0069006E0020004D007900530051004C002000470052004F00550050005F0043004F004E004300410054002000660075006E00740069006F006E002E00000040000C000100460069006C0065004400650073006300720069007000740069006F006E0000000000470072006F007500700043006F006E00630061007400000040000F000100460069006C006500560065007200730069006F006E000000000031002E0030002E0034003800370037002E00340030003900340038000000000040001000010049006E007400650072006E0061006C004E0061006D0065000000470072006F007500700043006F006E006300610074002E0064006C006C0000004800120001004C006500670061006C0043006F007000790072006900670068007400000043006F0070007900720069006700680074002000A90020002000320030003100310000004800100001004F0072006900670069006E0061006C00460069006C0065006E0061006D0065000000470072006F007500700043006F006E006300610074002E0064006C006C00000038000C000100500072006F0064007500630074004E0061006D00650000000000470072006F007500700043006F006E00630061007400000044000F000100500072006F006400750063007400560065007200730069006F006E00000031002E0030002E0034003800370037002E00340030003900340038000000000048000F00010041007300730065006D0062006C0079002000560065007200730069006F006E00000031002E0030002E0034003800370037002E003400300039003400380000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000C000000803D00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - WITH PERMISSION_SET = SAFE; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -EXEC sys.sp_addextendedproperty - @name = N'URL', - @value = N'http://groupconcat.codeplex.com', - @level0type = N'ASSEMBLY', - @level0name = N'GroupConcat' -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating core.[GROUP_CONCAT_D]...'; -GO -CREATE AGGREGATE core.[GROUP_CONCAT_D](@VALUE NVARCHAR (4000), @DELIMITER NVARCHAR (4)) - RETURNS NVARCHAR (MAX) - EXTERNAL NAME [GroupConcat].[GroupConcat.GROUP_CONCAT_D]; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating core.[GROUP_CONCAT_S]...'; -GO -CREATE AGGREGATE core.[GROUP_CONCAT_S](@VALUE NVARCHAR (4000), @SORT_ORDER TINYINT) - RETURNS NVARCHAR (MAX) - EXTERNAL NAME [GroupConcat].[GroupConcat.GROUP_CONCAT_S]; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating core.[GROUP_CONCAT_DS]...'; -GO -CREATE AGGREGATE core.[GROUP_CONCAT_DS](@VALUE NVARCHAR (4000), @DELIMITER NVARCHAR (4), @SORT_ORDER TINYINT) - RETURNS NVARCHAR (MAX) - EXTERNAL NAME [GroupConcat].[GroupConcat.GROUP_CONCAT_DS]; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -------------------------------------------------------------------------------------------------------------------- -PRINT N'Creating core.[GROUP_CONCAT]...'; -GO -CREATE AGGREGATE core.[GROUP_CONCAT](@VALUE NVARCHAR (4000)) - RETURNS NVARCHAR (MAX) - EXTERNAL NAME [GroupConcat].[GroupConcat.GROUP_CONCAT]; -GO -IF @@ERROR <> 0 - AND @@TRANCOUNT > 0 - BEGIN - ROLLBACK; - END -IF @@TRANCOUNT = 0 - BEGIN - INSERT INTO #tmpErrors (Error) - VALUES (1); - BEGIN TRANSACTION; - END -GO -------------------------------------------------------------------------------------------------------------------- - --- Create (or replace) a simple function that returns the version number of the newly installed function -IF EXISTS (SELECT * - FROM sys.objects - WHERE object_id = OBJECT_ID(N'core.GroupConcatVersion') - AND type = N'FN') - DROP FUNCTION core.GroupConcatVersion; -GO - -CREATE FUNCTION core.GroupConcatVersion() - RETURNS VARCHAR(100) - BEGIN - RETURN '1.00.23696'; - END; -GO - -IF EXISTS (SELECT * FROM #tmpErrors) ROLLBACK TRANSACTION -GO -IF @@TRANCOUNT>0 BEGIN -PRINT N'The transacted portion of the database update succeeded.' -COMMIT TRANSACTION -END -ELSE PRINT N'The transacted portion of the database update failed.' -GO -DROP TABLE #tmpErrors -------------------------------------------------------------------------------------------------------------------- -GO diff --git a/core/resources/schemas/dbscripts/sqlserver/group_concat_uninstall.sql b/core/resources/schemas/dbscripts/sqlserver/group_concat_uninstall.sql deleted file mode 100644 index c5593400742..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/group_concat_uninstall.sql +++ /dev/null @@ -1,44 +0,0 @@ -/* - - Copyright (c) 2011-2013 opcthree - - Simple uninstall script for SQL Server GROUP_CONCAT CLR functions, http://groupconcat.codeplex.com/ - - */ - -IF EXISTS ( SELECT * - FROM sys.objects - WHERE object_id = OBJECT_ID(N'core.[GROUP_CONCAT]') - AND type = N'AF' ) - DROP AGGREGATE core.[GROUP_CONCAT] -GO - -IF EXISTS ( SELECT * - FROM sys.objects - WHERE object_id = OBJECT_ID(N'core.[GROUP_CONCAT_D]') - AND type = N'AF' ) - DROP AGGREGATE core.[GROUP_CONCAT_D] -GO - -IF EXISTS ( SELECT * - FROM sys.objects - WHERE object_id = OBJECT_ID(N'core.[GROUP_CONCAT_DS]') - AND type = N'AF' ) - DROP AGGREGATE core.[GROUP_CONCAT_DS] -GO - -IF EXISTS ( SELECT * - FROM sys.objects - WHERE object_id = OBJECT_ID(N'core.[GROUP_CONCAT_S]') - AND type = N'AF' ) - DROP AGGREGATE core.[GROUP_CONCAT_S] -GO - -IF EXISTS ( SELECT * - FROM sys.assemblies asms - WHERE asms.name = N'GroupConcat' - AND is_user_defined = 1 ) - DROP ASSEMBLY [GroupConcat] -GO - ---EO uninstall diff --git a/core/resources/schemas/dbscripts/sqlserver/ignored_scripts.txt b/core/resources/schemas/dbscripts/sqlserver/ignored_scripts.txt deleted file mode 100644 index b4795cb666f..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/ignored_scripts.txt +++ /dev/null @@ -1,5 +0,0 @@ -enable_clr.sql -group_concat_install.sql -group_concat_install_1.00.23696.sql -group_concat_uninstall.sql -labkey-0.00-13.30.sql \ No newline at end of file diff --git a/core/resources/schemas/dbscripts/sqlserver/labkey-0.00-13.30.sql b/core/resources/schemas/dbscripts/sqlserver/labkey-0.00-13.30.sql deleted file mode 100644 index 982833cef1a..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/labkey-0.00-13.30.sql +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2013 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE SCHEMA labkey; -GO - -CREATE TABLE labkey.Schemas -( - CreatedBy INT, - Created DATETIME, - ModifiedBy INT, - Modified DATETIME, - - Name NVARCHAR(255) NOT NULL, - ModuleName NVARCHAR(255) NOT NULL, - InstalledVersion FLOAT NOT NULL, - - CONSTRAINT PK_Schemas PRIMARY KEY (Name) -); - -CREATE TABLE labkey.SqlScripts -( - CreatedBy INT, - Created DATETIME, - ModifiedBy INT, - Modified DATETIME, - - ModuleName NVARCHAR(255) NOT NULL, - FileName NVARCHAR(300) NOT NULL, - - CONSTRAINT PK_SqlScripts PRIMARY KEY (ModuleName, FileName) -); diff --git a/core/resources/schemas/dbscripts/sqlserver/prop-0.000-25.000.sql b/core/resources/schemas/dbscripts/sqlserver/prop-0.000-25.000.sql deleted file mode 100644 index e49d2bf4cbf..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/prop-0.000-25.000.sql +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE SCHEMA prop; -GO - --- --- NOTE: Bug in PropertyManager means NULL can't be passed for ObjectId, Category, etc. right now --- --- ObjectId: EntityId or ContainerId this setting applies to --- Generally only global User settings would use NULL ObjectId --- Category: Category can be used to group related properties, --- Category can be NULL if the Key field is reasonably unique/descriptive --- UserId: Modules may use NULL UserId for general configuration --- -CREATE TABLE prop.PropertySets -( - "Set" INT IDENTITY(1,1), - ObjectId UNIQUEIDENTIFIER NULL, -- e.g. EntityId or ContainerID - Category VARCHAR(255) NULL, -- e.g. "org.labkey.api.MailingList", may be NULL - UserId USERID, - - CONSTRAINT PK_PropertySet PRIMARY KEY CLUSTERED ("Set"), - CONSTRAINT UQ_PropertySet UNIQUE (ObjectId, UserId, Category) -); - -ALTER TABLE prop.propertysets - ADD CONSTRAINT FK_PropertySets_ObjectId FOREIGN KEY (ObjectId) REFERENCES core.Containers (EntityId); - --- Add a column that specifies algorithm used to encrypt all values in this property set -ALTER TABLE prop.PropertySets - ADD Encryption VARCHAR(100) NOT NULL DEFAULT 'None'; - -CREATE TABLE prop.Properties -( - "Set" INT NOT NULL, - Name VARCHAR(255) NOT NULL, - Value VARCHAR(2000) NOT NULL, - - CONSTRAINT PK_Properties PRIMARY KEY CLUSTERED ("Set", Name) -); - -GO - --- Create real FKs to prevent orphaning in the future -ALTER TABLE prop.properties - ADD CONSTRAINT FK_Properties_Set FOREIGN KEY ("set") REFERENCES prop.PropertySets ("set"); - --- Remove limit on value length -ALTER TABLE prop.Properties ALTER COLUMN Value NVARCHAR(MAX); -GO - -ALTER TABLE prop.properties DROP CONSTRAINT PK_Properties; -GO - -ALTER TABLE prop.properties ALTER COLUMN Name NVARCHAR(400) NOT NULL; -ALTER TABLE prop.properties ADD CONSTRAINT PK_Properties PRIMARY KEY CLUSTERED ("Set", Name); - -GO - -CREATE PROCEDURE prop.Property_setValue(@Set INT, @Name VARCHAR(255), @Value NVARCHAR(max)) AS - BEGIN - IF (@Value IS NULL) - DELETE prop.Properties WHERE "Set" = @Set AND Name = @Name - ELSE - BEGIN - UPDATE prop.Properties SET Value = @Value WHERE "Set" = @Set AND Name = @Name - IF (@@ROWCOUNT = 0) - INSERT prop.Properties VALUES (@Set, @Name, @Value) - END - END; - -GO diff --git a/core/resources/schemas/dbscripts/sqlserver/prop-create.sql b/core/resources/schemas/dbscripts/sqlserver/prop-create.sql deleted file mode 100644 index 4e47d5db0a7..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/prop-create.sql +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE VIEW prop.PropertyEntries AS - SELECT ObjectId, Category, UserId, Name, Value FROM prop.Properties JOIN prop.PropertySets ON prop.PropertySets."Set" = prop.Properties."Set" WHERE Encryption = 'None'; - - diff --git a/core/resources/schemas/dbscripts/sqlserver/prop-drop.sql b/core/resources/schemas/dbscripts/sqlserver/prop-drop.sql deleted file mode 100644 index 0c4829477f9..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/prop-drop.sql +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - --- DROP all views (current and obsolete) - --- NOTE: Don't remove any of these drop statements, even if we stop re-creating the view in *-create.sql. Drop statements must --- remain in place so we can correctly upgrade from older versions, which we commit to for two years after each release. - -EXEC core.fn_dropifexists 'PropertyEntries', 'prop', 'VIEW', NULL; diff --git a/core/resources/schemas/dbscripts/sqlserver/test-0.00-15.10.sql b/core/resources/schemas/dbscripts/sqlserver/test-0.00-15.10.sql deleted file mode 100644 index 570f42750b4..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/test-0.00-15.10.sql +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2017-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* test-0.00-12.10.sql */ - -CREATE SCHEMA test; -GO - -CREATE TABLE test.TestTable -( - _ts TIMESTAMP, - EntityId ENTITYID DEFAULT NEWID(), - RowId INT IDENTITY(1,1), - CreatedBy USERID, - Created DATETIME, - - Container ENTITYID, --container/path - Text NVARCHAR(195), --filename - - IntNull INT NULL, - IntNotNull INT NOT NULL, - DatetimeNull DATETIME NULL, - DatetimeNotNull DATETIME NOT NULL, - RealNull REAL NULL, - BitNull Bit NULL, - BitNotNull Bit NOT NULL, - - CONSTRAINT PK_TestTable PRIMARY KEY (RowId) -); - -/* test-13.10-13.20.sql */ - -CREATE TABLE test.TestTable2 -( - _ts TIMESTAMP, - EntityId ENTITYID DEFAULT NEWID(), - RowId INT IDENTITY(1,1), - CreatedBy USERID, - Created DATETIME, - - Container ENTITYID, --container/path - Text NVARCHAR(195), --filename - - IntNull INT NULL, - IntNotNull INT NOT NULL, - DatetimeNull DATETIME NULL, - DatetimeNotNull DATETIME NOT NULL, - RealNull REAL NULL, - BitNull Bit NULL, - BitNotNull Bit NOT NULL, - - CONSTRAINT PK_TestTable2 PRIMARY KEY (Container,Text) -); - -/* test-14.32-14.33.sql */ - --- These are used to test several different synonym scenarios - -CREATE SYNONYM test.TestTable3 FOR test.TestTable; -- Table in test schema -CREATE SYNONYM test.Containers2 FOR core.Containers; -- Table in another schema, with an FK to itself -CREATE SYNONYM test.ContainerAliases2 FOR core.ContainerAliases; -- Table in another schema, with an FK to the synonym above -CREATE SYNONYM test.Users2 FOR core.Users; -- View in another schema \ No newline at end of file diff --git a/core/resources/schemas/dbscripts/sqlserver/test-create.sql b/core/resources/schemas/dbscripts/sqlserver/test-create.sql deleted file mode 100644 index 6a6a4ab2269..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/test-create.sql +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2021 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - --- Verify that LabKey escapes LIKE wild card characters in table names correctly -CREATE VIEW test."a$b" AS - SELECT * FROM test.TestTable; - -GO - -CREATE VIEW test."a_b" AS - SELECT * FROM core.Containers; - -GO - -CREATE VIEW test."a%b" AS - SELECT * FROM core.ContainerAliases; - -GO - -CREATE VIEW test."a\b" AS - SELECT * FROM core.Users; \ No newline at end of file diff --git a/core/resources/schemas/dbscripts/sqlserver/test-drop.sql b/core/resources/schemas/dbscripts/sqlserver/test-drop.sql deleted file mode 100644 index febfa23d08b..00000000000 --- a/core/resources/schemas/dbscripts/sqlserver/test-drop.sql +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2021-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -DROP VIEW IF EXISTS test."a$b"; -DROP VIEW IF EXISTS test."a_b"; -DROP VIEW IF EXISTS test."a%b"; -DROP VIEW IF EXISTS test."a\b"; diff --git a/core/src/org/labkey/core/CoreModule.java b/core/src/org/labkey/core/CoreModule.java index 9a7ef72f8b0..468b828bfcd 100644 --- a/core/src/org/labkey/core/CoreModule.java +++ b/core/src/org/labkey/core/CoreModule.java @@ -517,23 +517,20 @@ public QuerySchema createSchema(DefaultSchema schema, Module module) } }); - if (CoreSchema.getInstance().getSqlDialect().isPostgreSQL()) + DefaultSchema.registerProvider(BasePostgreSqlDialect.POSTGRES_SCHEMA_NAME, new DefaultSchema.SchemaProvider(this) { - DefaultSchema.registerProvider(BasePostgreSqlDialect.POSTGRES_SCHEMA_NAME, new DefaultSchema.SchemaProvider(this) + @Override + public boolean isAvailable(DefaultSchema schema, Module module) { - @Override - public boolean isAvailable(DefaultSchema schema, Module module) - { - return schema.getContainer().isRoot() && schema.getContainer().hasPermission(schema.getUser(), TroubleshooterPermission.class); - } + return schema.getContainer().isRoot() && schema.getContainer().hasPermission(schema.getUser(), TroubleshooterPermission.class); + } - @Override - public QuerySchema createSchema(DefaultSchema schema, Module module) - { - return new PostgresUserSchema(schema.getUser(), schema.getContainer()); - } - }); - } + @Override + public QuerySchema createSchema(DefaultSchema schema, Module module) + { + return new PostgresUserSchema(schema.getUser(), schema.getContainer()); + } + }); OptionalFeatureService.get().addExperimentalFeatureFlag(NotificationMenuView.EXPERIMENTAL_NOTIFICATION_MENU, "Notifications Menu", "Notifications 'inbox' count display in the header bar with click to show the notifications panel of unread notifications.", false, true); @@ -1255,17 +1252,14 @@ public void moduleStartupComplete(ServletContext servletContext) results.put("archivedFolderCount", ContainerManager.getArchivedContainerCount()); results.put("databaseSize", CoreSchema.getInstance().getSchema().getScope().getDatabaseSize()); - if (CoreSchema.getInstance().getSqlDialect().isPostgreSQL()) - { - // Exclude temp schema to avoid PG exceptions when tables are appearing/disappearing during execution - // Note that they can be non-trivial in size. - SQLFragment sql = new SQLFragment("SELECT table_schema, SUM(total_size) FROM "); - sql.append(new PostgresTableSizesTable(new PostgresUserSchema(User.getAdminServiceUser(), ContainerManager.getRoot())), "t"); - sql.append(" WHERE table_schema != 'temp' GROUP BY table_schema"); - - var schemaSizes = new SqlSelector(CoreSchema.getInstance().getSchema(), sql).getValueMap(); - results.put("databaseSchemaSize", schemaSizes); - } + // Exclude temp schema to avoid PG exceptions when tables are appearing/disappearing during execution + // Note that they can be non-trivial in size. + SQLFragment sql = new SQLFragment("SELECT table_schema, SUM(total_size) FROM "); + sql.append(new PostgresTableSizesTable(new PostgresUserSchema(User.getAdminServiceUser(), ContainerManager.getRoot())), "t"); + sql.append(" WHERE table_schema != 'temp' GROUP BY table_schema"); + + var schemaSizes = new SqlSelector(CoreSchema.getInstance().getSchema(), sql).getValueMap(); + results.put("databaseSchemaSize", schemaSizes); results.put("scriptEngines", LabKeyScriptEngineManager.get().getScriptEngineMetrics()); results.put("customLabels", CustomLabelService.get().getCustomLabelMetrics()); diff --git a/core/src/org/labkey/core/FileBasedModules.md b/core/src/org/labkey/core/FileBasedModules.md index 20fc8811fb2..afeb5e25fb9 100644 --- a/core/src/org/labkey/core/FileBasedModules.md +++ b/core/src/org/labkey/core/FileBasedModules.md @@ -40,8 +40,7 @@ myModule/ │ └── [view_name].webpart.xml ├── schemas/ # Database schema definitions │ └── dbscripts/ - │ ├── postgresql/ - │ └── sqlserver/ + │ └── postgresql/ ├── web/ # JavaScript, CSS, images │ └── [moduleName]/ │ ├── [moduleName].js @@ -90,7 +89,6 @@ RequiredServerVersion: 23.11 - **SchemaVersion**: Version number for SQL schema upgrade scripts (e.g., `1.00`) - **ManageVersion**: Boolean (true/false) for schema version management - **BuildType**: "Development" or "Production" -- **SupportedDatabases**: "pgsql" or "mssql" (comma-separated) - **URL**: Homepage URL for the module ### Auto-Generated Properties (Don't Set) @@ -363,7 +361,6 @@ Simply refresh your browser to see changes. ### Maintenance - Version your module.properties appropriately - Document breaking changes in your README -- Test on both PostgreSQL and SQL Server if supporting both - Keep module.properties up to date with RequiredServerVersion ## Common Patterns diff --git a/core/src/org/labkey/core/admin/AdminController.java b/core/src/org/labkey/core/admin/AdminController.java index aada2d04fd8..60e3fa4e43f 100644 --- a/core/src/org/labkey/core/admin/AdminController.java +++ b/core/src/org/labkey/core/admin/AdminController.java @@ -506,12 +506,9 @@ public static void registerAdminConsoleLinks() AdminConsole.addLink(Diagnostics, "environment variables", new ActionURL(EnvironmentVariablesAction.class, root), SiteAdminPermission.class); AdminConsole.addLink(Diagnostics, "memory usage", new ActionURL(MemTrackerAction.class, root)); - if (CoreSchema.getInstance().getSqlDialect().isPostgreSQL()) - { - AdminConsole.addLink(Diagnostics, "postgres activity", new ActionURL(PostgresStatActivityAction.class, root)); - AdminConsole.addLink(Diagnostics, "postgres locks", new ActionURL(PostgresLocksAction.class, root)); - AdminConsole.addLink(Diagnostics, "postgres table sizes", new ActionURL(PostgresTableSizesAction.class, root)); - } + AdminConsole.addLink(Diagnostics, "postgres activity", new ActionURL(PostgresStatActivityAction.class, root)); + AdminConsole.addLink(Diagnostics, "postgres locks", new ActionURL(PostgresLocksAction.class, root)); + AdminConsole.addLink(Diagnostics, "postgres table sizes", new ActionURL(PostgresTableSizesAction.class, root)); AdminConsole.addLink(Diagnostics, "profiler", new ActionURL(MiniProfilerController.ManageAction.class, root)); AdminConsole.addLink(Diagnostics, "queries", getQueriesURL(null)); @@ -2693,11 +2690,6 @@ protected QueryView createQueryView(QueryExportForm form, BindException errors, throw new NotFoundException("Available only in the root container"); } - if (!CoreSchema.getInstance().getSqlDialect().isPostgreSQL()) - { - throw new NotFoundException("Available only with Postgres as the primary database"); - } - return super.createQueryView(form, errors, forExport, dataRegion); } diff --git a/core/src/org/labkey/core/admin/sql/ScriptReorderer.java b/core/src/org/labkey/core/admin/sql/ScriptReorderer.java index f1ddf86bd22..e26851c2b84 100644 --- a/core/src/org/labkey/core/admin/sql/ScriptReorderer.java +++ b/core/src/org/labkey/core/admin/sql/ScriptReorderer.java @@ -57,22 +57,11 @@ public class ScriptReorderer _schema = schema; _contents = contents; - if (_schema.getSqlDialect().isSqlServer()) - { - SCHEMA_NAME_REGEX = "(((\\w+)|(\\[\\w+\\]))\\.)?"; // optional [] around schema name - TABLE_NAME_REGEX = "(?" + SCHEMA_NAME_REGEX + "((#?\\w+)|(\\[#?\\w+\\])))"; // # allows for temp table names, optional [] around table name - TABLE_NAME_NO_UNDERSCORE_REGEX = null; - STATEMENT_ENDING_REGEX = "((; GO\\s*$)|(;\\s*$)|( GO\\s*$))\\s*"; // Semicolon, GO, or both - CONSTRAINT_NAME_REGEX = "(?((\\w+)|(\\[\\w+\\])))"; // optional [] around name - } - else - { - SCHEMA_NAME_REGEX = "((\\w+)\\.)?"; - TABLE_NAME_REGEX = "(?
" + SCHEMA_NAME_REGEX + "(\\w+))"; - TABLE_NAME_NO_UNDERSCORE_REGEX = "(?
" + SCHEMA_NAME_REGEX + "([[a-zA-Z0-9]]+))"; - STATEMENT_ENDING_REGEX = ";(\\s*?)((--)[^\\n]*)?$(\\s*)"; - CONSTRAINT_NAME_REGEX = "(?(\\w+))"; - } + SCHEMA_NAME_REGEX = "((\\w+)\\.)?"; + TABLE_NAME_REGEX = "(?
" + SCHEMA_NAME_REGEX + "(\\w+))"; + TABLE_NAME_NO_UNDERSCORE_REGEX = "(?
" + SCHEMA_NAME_REGEX + "([[a-zA-Z0-9]]+))"; + STATEMENT_ENDING_REGEX = ";(\\s*?)((--)[^\\n]*)?$(\\s*)"; + CONSTRAINT_NAME_REGEX = "(?(\\w+))"; TABLE_NAME2_REGEX = TABLE_NAME_REGEX.replace("table", "table2"); @@ -102,46 +91,24 @@ public String getReorderedScript(boolean isHtml) patterns.add(new SqlPattern(getRegExWithPrefix("DROP TABLE (IF EXISTS )?"), Type.Table, Operation.Other)); - if (_schema.getSqlDialect().isSqlServer()) - { - patterns.add(new SqlPattern(getRegExWithPrefix("CREATE TABLE "), Type.Table, Operation.Other)); + patterns.add(new SqlPattern("ALTER TABLE " + TABLE_NAME_REGEX + " RENAME TO " + TABLE_NAME2_REGEX + STATEMENT_ENDING_REGEX, Type.Table, Operation.RenameTable)); + patterns.add(new SqlPattern(getRegExWithPrefix("CREATE (TEMPORARY )?TABLE "), Type.Table, Operation.Other)); + patterns.add(new SqlPattern("SELECT core\\.fn_dropifexists\\s*\\('(?
\\w+)'\\s*,\\s*'(?\\w+)'\\s*,\\s*'(TABLE|COLUMN|INDEX|DEFAULT|CONSTRAINT)'.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); + patterns.add(new SqlPattern("SELECT core\\.fn_dropifexists\\s*\\('(\\w+)'\\s*,\\s*'(?\\w+)'.+?" + STATEMENT_ENDING_REGEX, Type.NonTable, Operation.Other)); + patterns.add(new SqlPattern("SELECT SETVAL\\('" + TABLE_NAME_NO_UNDERSCORE_REGEX + "_.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); + patterns.add(new SqlPattern(getRegExWithPrefix("CLUSTER \\w+ ON "), Type.Table, Operation.Other)); // e.g. CLUSTER PK_Keyword ON flow.Keyword + patterns.add(new SqlPattern(getRegExWithPrefix("CLUSTER "), Type.Table, Operation.Other)); + patterns.add(new SqlPattern(getRegExWithPrefix("ANALYZE "), Type.Table, Operation.Other)); - // Specific sp_rename pattern for table rename - patterns.add(new SqlPattern("(EXEC(UTE)? )?sp_rename (@objname\\s*=\\s*)?'" + TABLE_NAME_REGEX + "'\\s*,\\s*'" + TABLE_NAME2_REGEX + "'" + STATEMENT_ENDING_REGEX, Type.Table, Operation.RenameTable)); + // Can't prefix index names with table name on PostgreSQL... find table name based on our naming conventions. + patterns.add(new SqlPattern("(DROP|ALTER) INDEX (IF EXISTS )?" + SCHEMA_NAME_REGEX + "(IX_|IDX_|UQ_)" + TABLE_NAME_REGEX + "_.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - // All other sp_renames - patterns.add(new SqlPattern("(EXEC(UTE)? )?sp_rename (@objname\\s*=\\s*)?'" + TABLE_NAME_REGEX + ".*?'.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - patterns.add(new SqlPattern("EXEC(UTE)? core\\.fn_dropifexists\\s*(@objname\\s*=\\s*)?'(?
\\w+)'\\s*,\\s*(@objschema\\s*=\\s*)?'(?\\w+)'\\s*,\\s*(@objtype\\s*=\\s*)?'(TABLE|COLUMN|INDEX|DEFAULT|CONSTRAINT)'.*?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - patterns.add(new SqlPattern("EXEC(UTE)? core\\.fn_dropifexists\\s*'(\\w+)'\\s*,\\s*'(?\\w+)'.*?" + STATEMENT_ENDING_REGEX, Type.NonTable, Operation.Other)); + // Find table name based on sequence naming conventions + patterns.add(new SqlPattern("CREATE SEQUENCE " + TABLE_NAME_REGEX + "_.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - // DROP INDEX on SQL Server follows a similar pattern to CREATE INDEX (above) - patterns.add(new SqlPattern("DROP INDEX (IF EXISTS )?\\w+ ON " + TABLE_NAME_REGEX + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - - patterns.add(new SqlPattern("(CREATE|ALTER) PROCEDURE .+?" + STATEMENT_ENDING_REGEX, Type.NonTable, Operation.Other)); - patterns.add(new SqlPattern("(CREATE|ALTER) TRIGGER .+?" + "END GO\\s*$", Type.NonTable, Operation.Other)); - patterns.add(new SqlPattern("ALTER TABLE " + TABLE_NAME_REGEX + " CHECK CONSTRAINT " + CONSTRAINT_NAME_REGEX + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - } - else - { - patterns.add(new SqlPattern("ALTER TABLE " + TABLE_NAME_REGEX + " RENAME TO " + TABLE_NAME2_REGEX + STATEMENT_ENDING_REGEX, Type.Table, Operation.RenameTable)); - patterns.add(new SqlPattern(getRegExWithPrefix("CREATE (TEMPORARY )?TABLE "), Type.Table, Operation.Other)); - patterns.add(new SqlPattern("SELECT core\\.fn_dropifexists\\s*\\('(?
\\w+)'\\s*,\\s*'(?\\w+)'\\s*,\\s*'(TABLE|COLUMN|INDEX|DEFAULT|CONSTRAINT)'.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - patterns.add(new SqlPattern("SELECT core\\.fn_dropifexists\\s*\\('(\\w+)'\\s*,\\s*'(?\\w+)'.+?" + STATEMENT_ENDING_REGEX, Type.NonTable, Operation.Other)); - patterns.add(new SqlPattern("SELECT SETVAL\\('" + TABLE_NAME_NO_UNDERSCORE_REGEX + "_.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - patterns.add(new SqlPattern(getRegExWithPrefix("CLUSTER \\w+ ON "), Type.Table, Operation.Other)); // e.g. CLUSTER PK_Keyword ON flow.Keyword - patterns.add(new SqlPattern(getRegExWithPrefix("CLUSTER "), Type.Table, Operation.Other)); - patterns.add(new SqlPattern(getRegExWithPrefix("ANALYZE "), Type.Table, Operation.Other)); - - // Can't prefix index names with table name on PostgreSQL... find table name based on our naming conventions. - patterns.add(new SqlPattern("(DROP|ALTER) INDEX (IF EXISTS )?" + SCHEMA_NAME_REGEX + "(IX_|IDX_|UQ_)" + TABLE_NAME_REGEX + "_.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - - // Find table name based on sequence naming conventions - patterns.add(new SqlPattern("CREATE SEQUENCE " + TABLE_NAME_REGEX + "_.+?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); - - patterns.add(new SqlPattern("CREATE (OR REPLACE )?FUNCTION .+? RETURNS \\w+ AS (\\S+) (.+?) \\2 LANGUAGE (plpgsql|SQL)( STRICT)?( IMMUTABLE)?( VOLATILE)?( COST \\d+)?" + STATEMENT_ENDING_REGEX, Type.NonTable, Operation.Other)); - patterns.add(new SqlPattern(getRegExWithPrefix("COMMENT ON TABLE "), Type.Table, Operation.Other)); - patterns.add(new SqlPattern("DO (\\S+) (.+?) END \\1" + STATEMENT_ENDING_REGEX, Type.NonTable, Operation.Other)); - } + patterns.add(new SqlPattern("CREATE (OR REPLACE )?FUNCTION .+? RETURNS \\w+ AS (\\S+) (.+?) \\2 LANGUAGE (plpgsql|SQL)( STRICT)?( IMMUTABLE)?( VOLATILE)?( COST \\d+)?" + STATEMENT_ENDING_REGEX, Type.NonTable, Operation.Other)); + patterns.add(new SqlPattern(getRegExWithPrefix("COMMENT ON TABLE "), Type.Table, Operation.Other)); + patterns.add(new SqlPattern("DO (\\S+) (.+?) END \\1" + STATEMENT_ENDING_REGEX, Type.NonTable, Operation.Other)); patterns.add(new SqlPattern("ALTER TABLE " + TABLE_NAME_REGEX + " (WITH CHECK )?ADD CONSTRAINT " + CONSTRAINT_NAME_REGEX + " FOREIGN KEY\\s*\\([^\\)]+?\\) REFERENCES " + TABLE_NAME2_REGEX + " \\([^\\)]+?\\).*?" + STATEMENT_ENDING_REGEX, Type.Table, Operation.Other)); // Put this at the end to capture all other ALTER TABLE statements (i.e., not RENAMEs) @@ -217,9 +184,7 @@ public String getReorderedScript(boolean isHtml) // Stash a normalized version of the constraint name so we can save it to the map associated // with its table (below). Also, if a second table is not specified and we can determine the // constraint's table from the map, then set it as tableName2. This ensures the statement is - // output after its CREATE statement. For example, a SQL Server statement like ALTER TABLE - // MyTable CHECK CONSTRAINT MyConstraint may need to be output after the second table from the - // original CREATE statement. + // output after its CREATE statement. String constraintName = m.group("constraint"); assert constraintName != null; constraintKey = normalizeName(constraintName); diff --git a/core/src/org/labkey/core/admin/sql/SqlScriptController.java b/core/src/org/labkey/core/admin/sql/SqlScriptController.java index 42305e175b7..afee8e77ffe 100644 --- a/core/src/org/labkey/core/admin/sql/SqlScriptController.java +++ b/core/src/org/labkey/core/admin/sql/SqlScriptController.java @@ -68,7 +68,6 @@ import org.labkey.api.util.LinkBuilder; import org.labkey.api.util.PageFlowUtil; import org.labkey.api.util.Pair; -import org.labkey.api.util.Path; import org.labkey.api.util.QuietCloser; import org.labkey.api.util.SqlUtil; import org.labkey.api.util.TestContext; @@ -1129,13 +1128,6 @@ protected void renderButtons(SqlScript script, PrintWriter out) .href(getScriptURL(CleanUpScriptAction.class, script)) .tooltip("Remove redundant and unnecessary statements. This uses AI, so it may take some time and its results must be carefully reviewed.") ); - SqlDialect dialect = script.getSchema().getSqlDialect(); - String theOther = getTheOtherDialectDescription(script.getSchema().getSqlDialect()); - out.println( - PageFlowUtil.button("Migrate to " + theOther) - .href(getScriptURL(MigrateScriptAction.class, script)) - .tooltip("Migrate this " + dialect.getProductName() + " SQL script to " + theOther + " syntax. This uses AI, so it may take some time and its results must be carefully reviewed.") - ); } } } @@ -1325,7 +1317,7 @@ public class CleanUpScriptAction extends BaseAIScriptAction @Override protected String getPrompt(SqlDialect dialect, SqlScript script) { - String youAre = "You are a " + dialect.getProductName() + (dialect.isSqlServer() ? " T-SQL" : " SQL") + " expert.\n"; + String youAre = "You are a " + dialect.getProductName() + " SQL expert.\n"; String yourTask = "Your task is to clean up this " + dialect.getProductName() + " SQL script" + (script.getFromVersion() == 0.0 ? ", which creates a brand new database schema and populates it with tables" : "") + ".\n"; return youAre + yourTask + CLEAN_UP_PROMPT; } @@ -1343,56 +1335,6 @@ protected String getActionDescription() } } - private static String getTheOtherDialectDescription(SqlDialect dialect) - { - return dialect.isPostgreSQL() ? "Microsoft SQL Server" : "PostgreSQL"; - } - - private static String getTheOtherScriptDir(SqlDialect dialect) - { - return dialect.isPostgreSQL() ? "sqlserver" : "postgresql"; - } - - private static final String MIGRATE_TO_PG_PROMPT = """ - Note that `ENTITYID`, `UNIQUEIDENTIFIER`, and `USERID` data types are available on both databases. Maintain - these data types when migrating the script (do not replace `ENTITYID` with `VARCHAR(36)` or `USERID` with `INT`, - for example). - - Include a summary of the changes you made at the end. - """; - - @RequiresPermission(AdminOperationsPermission.class) - public class MigrateScriptAction extends BaseAIScriptAction - { - @Override - protected String getPrompt(SqlDialect dialect, SqlScript script) - { - String youAre = "You are an expert in Microsoft SQL Server T-SQL and PostgreSQL SQL.\n"; - String yourTask = "Given this " + dialect.getProductName() + " SQL script, create an equivalent SQL script that's compatible with " + getTheOtherDialectDescription(dialect) + ".\n"; - return youAre + yourTask + MIGRATE_TO_PG_PROMPT; - } - - @Override - protected String getChatName() - { - return "SQL Script Migrator"; - } - - @Override - protected String getActionDescription() - { - return "Migrate " + super.getActionDescription(); - } - - @Override - protected ActionURL getSaveScriptActionURL(SqlScript script, String newContents, @Nullable File scriptDir) - { - SqlDialect dialect = script.getSchema().getSqlDialect(); - File dbscripts = ((FileSqlScriptProvider)script.getProvider()).getScriptDirectory(dialect).getParentFile(); - scriptDir = FileUtil.appendPath(dbscripts, Path.parse(getTheOtherScriptDir(dialect))); - return super.getSaveScriptActionURL(script, newContents, scriptDir); - } - } private record ScriptToSave(SqlScript script, String contents, @Nullable File scriptsDir) {} diff --git a/core/src/org/labkey/core/attachment/AttachmentServiceImpl.java b/core/src/org/labkey/core/attachment/AttachmentServiceImpl.java index f46f457ada1..59f3aa8182e 100644 --- a/core/src/org/labkey/core/attachment/AttachmentServiceImpl.java +++ b/core/src/org/labkey/core/attachment/AttachmentServiceImpl.java @@ -808,7 +808,7 @@ private SQLFragment getSelectStatement(ColumnInfo column, boolean lsidsOnly) } else if (Strings.CI.endsWith(column.getName(), "LSID")) { - Pair pair = Lsid.getSqlExpressionToExtractObjectId(column.getSelectIdentifier().getSql(), column.getSqlDialect()); + Pair pair = Lsid.getSqlExpressionToExtractObjectId(column.getSelectIdentifier().getSql()); expression = pair.first; where = pair.second; } diff --git a/core/src/org/labkey/core/query/ModulesTableInfo.java b/core/src/org/labkey/core/query/ModulesTableInfo.java index 53aa5d4a2b1..8166515c7d2 100644 --- a/core/src/org/labkey/core/query/ModulesTableInfo.java +++ b/core/src/org/labkey/core/query/ModulesTableInfo.java @@ -27,7 +27,6 @@ import org.labkey.api.data.RenderContext; import org.labkey.api.data.SQLFragment; import org.labkey.api.data.dialect.DialectStringHandler; -import org.labkey.api.data.dialect.SqlDialect; import org.labkey.api.module.Module; import org.labkey.api.module.ModuleContext; import org.labkey.api.module.ModuleLoader; @@ -156,17 +155,7 @@ private void appendBooleanLiteral(SQLFragment sql, String sep, boolean b) { sql.append(sep); - SqlDialect dialect = getSqlDialect(); - String literal = dialect.getBooleanLiteral(b); - - if (dialect.isSqlServer()) - { - sql.append("CAST (").append(literal).append(" AS BIT)"); - } - else - { - sql.append(literal); - } + sql.append(getSqlDialect().getBooleanLiteral(b)); } @NotNull diff --git a/core/test/src/org/labkey/test/tests/upgrade/EncryptionKeyUpgradeTest.java b/core/test/src/org/labkey/test/tests/upgrade/EncryptionKeyUpgradeTest.java index e18ce378ae3..de221340797 100644 --- a/core/test/src/org/labkey/test/tests/upgrade/EncryptionKeyUpgradeTest.java +++ b/core/test/src/org/labkey/test/tests/upgrade/EncryptionKeyUpgradeTest.java @@ -18,8 +18,6 @@ import org.junit.Test; import org.junit.experimental.categories.Category; import org.labkey.test.Locators; -import org.labkey.test.WebTestHelper; -import org.labkey.test.WebTestHelper.DatabaseType; import org.labkey.test.pages.ConfigureReportsAndScriptsPage; import org.labkey.test.pages.ConfigureReportsAndScriptsPage.EngineType; import org.labkey.test.pages.admin.RConfigurationPage; @@ -59,13 +57,10 @@ protected void doSetup() .setEngineOverrides(DUMMY_R_SERVE, DUMMY_R_SERVE) .save(); - if (WebTestHelper.getDatabaseType() == DatabaseType.PostgreSQL) - { - // Set StatusCake api key - EditUpgradeMessagePage.beginAt(this) - .setStatusCakeApiKey("password") - .save(); - } + // Set StatusCake api key + EditUpgradeMessagePage.beginAt(this) + .setStatusCakeApiKey("password") + .save(); } @Test @@ -84,12 +79,9 @@ public void testDummyRemoteREngine() @Test public void testStatusCakeApiKey() { - if (WebTestHelper.getDatabaseType() == DatabaseType.PostgreSQL) - { - // Just loading this page can trigger an error if there was a problem with the encryption - assertEquals("StatusCake API key input should be present but blank", - "", EditUpgradeMessagePage.beginAt(this, null).getStatusCakeApiKey()); // Use the root container in case the '_mothership' project doesn't exist - } + // Just loading this page can trigger an error if there was a problem with the encryption + assertEquals("StatusCake API key input should be present but blank", + "", EditUpgradeMessagePage.beginAt(this, null).getStatusCakeApiKey()); // Use the root container in case the '_mothership' project doesn't exist } @Override diff --git a/devtools/module.properties b/devtools/module.properties index 66c280d041d..30c73b883b2 100644 --- a/devtools/module.properties +++ b/devtools/module.properties @@ -3,5 +3,4 @@ Label: Developer tools and tests Description: For use during development, not intended for production License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/devtools/src/org/labkey/devtools/ToolsController.java b/devtools/src/org/labkey/devtools/ToolsController.java index 42b085ba78b..ff9a1052023 100644 --- a/devtools/src/org/labkey/devtools/ToolsController.java +++ b/devtools/src/org/labkey/devtools/ToolsController.java @@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.junit.Assert; -import org.junit.Assume; import org.junit.Test; import org.labkey.api.action.FormHandlerAction; import org.labkey.api.action.FormViewAction; @@ -47,7 +46,6 @@ import org.labkey.api.data.dialect.SqlDialect; import org.labkey.api.module.Module; import org.labkey.api.module.ModuleLoader; -import org.labkey.api.module.SupportedDatabase; import org.labkey.api.reader.Readers; import org.labkey.api.security.RequiresPermission; import org.labkey.api.security.permissions.AdminPermission; @@ -612,7 +610,7 @@ public ModelAndView getView(Object o, BindException errors) throws IOException for (ControllerActionId actionId : actionIds) { - Module module = ModuleLoader.getInstance().getModuleForController(actionId.getController().toLowerCase()); + Module module = ModuleLoader.getInstance().getModuleForController(actionId.controller().toLowerCase()); if (null == module) { @@ -620,8 +618,8 @@ public ModelAndView getView(Object o, BindException errors) throws IOException } else { - SpringActionController controller = (SpringActionController) module.getController(null, actionId.getController()); - if (null == controller || controller.resolveAction(actionId.getAction()) == null) + SpringActionController controller = (SpringActionController) module.getController(null, actionId.controller()); + if (null == controller || controller.resolveAction(actionId.action()) == null) { missingActions.add(actionId); } @@ -688,46 +686,12 @@ public void addNavTrail(NavTree root) root.addChild("Check Crawler Actions"); } - private static class ControllerActionId implements Comparable + private record ControllerActionId(String controller, String action) implements Comparable { - private final String _controller; - private final String _action; - - public ControllerActionId(String controller, String action) - { - _controller = controller; - _action = action; - } - - public String getController() - { - return _controller; - } - - public String getAction() - { - return _action; - } - - @Override + @Override @NotNull public String toString() { - return "/" + _controller + "-" + _action; - } - - @Override - public boolean equals(Object o) - { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - ControllerActionId that = (ControllerActionId) o; - return _controller.equals(that._controller) && _action.equals(that._action); - } - - @Override - public int hashCode() - { - return Objects.hash(_controller, _action); + return "/" + controller + "-" + action; } @Override @@ -738,30 +702,6 @@ public int compareTo(@NotNull ControllerActionId o) } } - @RequiresPermission(AdminPermission.class) - public class PostgreSqlOnlyModulesThatHaveSqlServerScriptsAction extends SimpleViewAction - { - @Override - public ModelAndView getView(Object o, BindException errors) - { - List names = ModuleLoader.getInstance().getModules().stream() - .filter(m -> !m.getSupportedDatabasesSet().contains(SupportedDatabase.mssql)) - .filter(m -> !StringUtils.isBlank(m.getSourcePath())) - .filter(m -> new File(m.getSourcePath(), "resources/schemas/dbscripts/sqlserver").exists()) - .map(Module::getName) - .toList(); - - return new HtmlView(HtmlString.of(names.isEmpty() ? "None" : names.toString())); - } - - @Override - public void addNavTrail(NavTree root) - { - addBeginNavTrail(root); - root.addChild("PostgreSQL-Only Modules That Still Have SQL Server Scripts"); - } - } - public record OverlappingIndicesForm(String schemaName, Boolean clearCaches) {} public record IndexChange(TableInfo table, IndexDefinition index, ChangeType type, String description) {} public record IndexOverlap(TableInfo table, String description) {} @@ -1137,7 +1077,6 @@ public static class TestCase extends Assert @Test public void testOverlappingIndices() { - Assume.assumeTrue("Skipping because this server is not running on PostgreSQL", DbScope.getLabKeyScope().getSqlDialect().isPostgreSQL()); var map = new OverlappingIndicesAnalyzer().getChanges(null); var keys = map.keys(); if (!keys.isEmpty()) @@ -1294,22 +1233,17 @@ void writeScript(Writer writer, IndexChange change, String schemaName, String ta { writer.write("-- " + change.description() + "\n"); - if (DbScope.getLabKeyScope().getSqlDialect().isPostgreSQL()) + if (dropIndex.indexType() == Unique) { - if (dropIndex.indexType() == Unique) + String constraintName = getConstraintForIndex(schemaName, dropIndex.name()); + if (constraintName != null) { - String constraintName = getConstraintForIndex(schemaName, dropIndex.name()); - if (constraintName != null) - { - writer.write("ALTER TABLE " + schemaName + "." + tableName + " DROP CONSTRAINT " + constraintName + ";\n"); - return; - } + writer.write("ALTER TABLE " + schemaName + "." + tableName + " DROP CONSTRAINT " + constraintName + ";\n"); + return; } - - writer.write("DROP INDEX " + schemaName + "." + dropIndex.name() + ";\n"); } - else - writer.write("DROP INDEX " + dropIndex.name() + " ON " + schemaName + "." + tableName + ";\n"); + + writer.write("DROP INDEX " + schemaName + "." + dropIndex.name() + ";\n"); } }, Convert diff --git a/experiment/module.properties b/experiment/module.properties index 87f167513ac..0e020a243d1 100644 --- a/experiment/module.properties +++ b/experiment/module.properties @@ -12,5 +12,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-0.000-25.000.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-0.000-25.000.sql deleted file mode 100644 index 43771839911..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-0.000-25.000.sql +++ /dev/null @@ -1,1245 +0,0 @@ -/* - * Copyright (c) 2019-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Creates experiment annotation tables in the exp schema base on FuGE-OM types - */ - -CREATE SCHEMA exp; -GO - --- Provisioned schema used by DataClassDomainKind -CREATE SCHEMA expdataclass; -GO - -CREATE SCHEMA expsampleset -GO - -EXEC sp_addtype 'LSIDtype', 'NVARCHAR(300)'; -GO - -CREATE TABLE exp.Protocol -( - RowId INT IDENTITY (1, 1) NOT NULL, - LSID LSIDtype NOT NULL, - Name NVARCHAR (200) NULL, - ProtocolDescription NTEXT NULL, - ApplicationType NVARCHAR (50) NULL, - MaxInputMaterialPerInstance INT NULL, - MaxInputDataPerInstance INT NULL, - OutputMaterialPerInstance INT NULL, - OutputDataPerInstance INT NULL, - OutputMaterialType NVARCHAR (50) NULL, - OutputDataType NVARCHAR (50) NULL, - Instrument NVARCHAR (200) NULL, - Software NVARCHAR (200) NULL, - ContactId NVARCHAR (100) NULL, - Created DATETIME NULL, - EntityId UNIQUEIDENTIFIER NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - Container EntityId NOT NULL, - - CONSTRAINT PK_Protocol PRIMARY KEY (RowId), - CONSTRAINT UQ_Protocol_LSID UNIQUE (LSID) -); - -CREATE INDEX IDX_Protocol_Container ON exp.Protocol (Container) -GO - -ALTER TABLE exp.Protocol ADD CONSTRAINT FK_Protocol_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); - -ALTER TABLE exp.Protocol ADD Status NVARCHAR(60); -GO - -CREATE TABLE exp.Experiment -( - RowId INT IDENTITY (1, 1) NOT NULL, - LSID LSIDtype NOT NULL, - Name NVARCHAR (200) NULL, - Hypothesis TEXT NULL, - ContactId NVARCHAR (100) NULL, - ExperimentDescriptionURL NVARCHAR (200) NULL, - Comments TEXT NULL, - EntityId UNIQUEIDENTIFIER NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - Container EntityId NOT NULL, - Hidden BIT NOT NULL DEFAULT 0, - BatchProtocolId INT NULL, - - CONSTRAINT PK_Experiment PRIMARY KEY (RowId), - CONSTRAINT UQ_Experiment_LSID UNIQUE (LSID), - CONSTRAINT FK_Experiment_BatchProtocolId FOREIGN KEY (BatchProtocolId) REFERENCES exp.Protocol (RowId) -); -CREATE INDEX IX_Experiment_Container ON exp.Experiment(Container); -CREATE INDEX IDX_Experiment_BatchProtocolId ON exp.Experiment(BatchProtocolId); -ALTER TABLE exp.Experiment ADD CONSTRAINT FK_Experiment_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); - -CREATE TABLE exp.ExperimentRun -( - RowId INT IDENTITY (1, 1) NOT NULL, - LSID LSIDtype NOT NULL, - Name NVARCHAR (100) NULL, - ProtocolLSID LSIDtype NOT NULL, - Comments NTEXT NULL, - EntityId UNIQUEIDENTIFIER NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - Container EntityId NOT NULL, - FilePathRoot NVARCHAR(500), - - CONSTRAINT PK_ExperimentRun PRIMARY KEY NONCLUSTERED (RowId), - CONSTRAINT UQ_ExperimentRun_LSID UNIQUE (LSID), - CONSTRAINT FK_ExperimentRun_Protocol FOREIGN KEY (ProtocolLSID) REFERENCES exp.Protocol (LSID) -); -CREATE CLUSTERED INDEX IX_CL_ExperimentRun_Container ON exp.ExperimentRun(Container); -CREATE INDEX IX_ExperimentRun_ProtocolLSID ON exp.ExperimentRun(ProtocolLSID); - -ALTER TABLE exp.ExperimentRun ADD CONSTRAINT FK_ExperimentRun_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); -ALTER TABLE exp.ExperimentRun ADD JobId INTEGER; - ---experiment module depends on pipeline, so this should be ok -ALTER TABLE exp.ExperimentRun ADD - CONSTRAINT FK_ExperimentRun_JobId FOREIGN KEY (JobId) - REFERENCES pipeline.statusfiles (RowId); - --- Change exp.ExperimentRun.Name from VARCHAR(100) to VARCHAR(200) to match other experiment table name columns -ALTER TABLE exp.ExperimentRun ALTER COLUMN Name NVARCHAR(200); - --- Add a column to track the chaining of original and replaced runs -ALTER TABLE exp.ExperimentRun ADD ReplacedByRunId INT; - -ALTER TABLE exp.ExperimentRun ADD - CONSTRAINT FK_ExperimentRun_ReplacedByRunId FOREIGN KEY (ReplacedByRunId) - REFERENCES exp.ExperimentRun (RowId); - -CREATE INDEX IDX_ExperimentRun_ReplacedByRunId ON exp.ExperimentRun(ReplacedByRunId); - --- Add batchId column to run table -ALTER TABLE exp.ExperimentRun ADD BatchId INT; - -ALTER TABLE exp.ExperimentRun ADD CONSTRAINT FK_ExperimentRun_BatchId FOREIGN KEY (BatchId) REFERENCES exp.Experiment (RowId); - -CREATE INDEX IX_ExperimentRun_BatchId ON exp.ExperimentRun(BatchId); - -GO - -ALTER TABLE exp.experimentrun ADD objectid INT; -ALTER TABLE exp.experimentrun ALTER COLUMN objectid INT NOT NULL; -CREATE UNIQUE INDEX idx_experimentrun_objectid ON exp.experimentrun (objectid); -ALTER TABLE exp.ExperimentRun ADD LastIndexed DATETIME NULL; - -ALTER TABLE exp.ExperimentRun ADD WorkflowTask INT; -GO -CREATE INDEX IDX_ExperimentRun_WorkflowTask ON exp.ExperimentRun(WorkflowTask); - -CREATE TABLE exp.ProtocolApplication -( - RowId INT IDENTITY (1, 1) NOT NULL, - LSID LSIDtype NOT NULL, - Name NVARCHAR (200) NULL, - CpasType NVARCHAR (50) NULL, - ProtocolLSID LSIDtype NOT NULL, - ActivityDate DATETIME NULL, - Comments NVARCHAR (2000) NULL, - RunId INT NOT NULL, - ActionSequence INT NOT NULL, - - CONSTRAINT PK_ProtocolApplication PRIMARY KEY NONCLUSTERED (RowId), - CONSTRAINT UQ_ProtocolApp_LSID UNIQUE (LSID), - CONSTRAINT FK_ProtocolApplication_ExperimentRun FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId), - CONSTRAINT FK_ProtocolApplication_Protocol FOREIGN KEY (ProtocolLSID) REFERENCES exp.Protocol (LSID) -); -CREATE CLUSTERED INDEX IX_CL_ProtocolApplication_RunId ON exp.ProtocolApplication(RunId); -CREATE INDEX IX_ProtocolApplication_ProtocolLSID ON exp.ProtocolApplication(ProtocolLSID); - --- add start time, end time, and record count to protocol application table for ETL tasks and others -ALTER TABLE exp.ProtocolApplication ADD StartTime DATETIME NULL; -ALTER TABLE exp.ProtocolApplication ADD EndTime DATETIME NULL; -ALTER TABLE exp.ProtocolApplication ADD RecordCount INT NULL; - -ALTER TABLE exp.ProtocolApplication ALTER COLUMN Comments NVARCHAR(MAX); - -ALTER TABLE exp.ProtocolApplication ADD EntityId ENTITYID; -GO - -ALTER TABLE exp.ProtocolApplication ALTER COLUMN EntityId ENTITYID NOT NULL; - -ALTER TABLE exp.ExperimentRun ADD CONSTRAINT FK_Run_WorfklowTask FOREIGN KEY (WorkflowTask) REFERENCES exp.ProtocolApplication (RowId) ON DELETE SET NULL; - -CREATE TABLE exp.Data -( - RowId INT IDENTITY (1, 1) NOT NULL, - LSID LSIDtype NOT NULL, - Name NVARCHAR (200) NULL, - CpasType NVARCHAR (50) NULL, - SourceApplicationId INT NULL, - DataFileUrl NVARCHAR (400) NULL, - RunId INT NULL, - Created DATETIME NOT NULL, - CreatedBy INT, - Modified DATETIME, - ModifiedBy INT, - Container EntityId NOT NULL, - - CONSTRAINT PK_Data PRIMARY KEY NONCLUSTERED (RowId), - CONSTRAINT UQ_Data_LSID UNIQUE (LSID), - CONSTRAINT FK_Data_ExperimentRun FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId), - CONSTRAINT FK_Data_ProtocolApplication FOREIGN KEY (SourceApplicationID) REFERENCES exp.ProtocolApplication (RowId), - CONSTRAINT FK_Data_Containers FOREIGN KEY (Container) REFERENCES core.Containers (EntityId) -); -CREATE CLUSTERED INDEX IX_CL_Data_RunId ON exp.Data(RunId); -CREATE INDEX IX_Data_Container ON exp.Data(Container); -CREATE INDEX IX_Data_SourceApplicationId ON exp.Data(SourceApplicationId); -CREATE INDEX IX_Data_DataFileUrl ON exp.Data(DataFileUrl); - -ALTER TABLE exp.Data ADD Generated BIT NOT NULL DEFAULT 0; -GO - -ALTER TABLE exp.data ADD description NVARCHAR(4000); -GO - -ALTER TABLE exp.data ADD classId INT; -GO - --- Within a DataClass, name must be unique. If DataClass is null, duplicate names are allowed. -CREATE UNIQUE INDEX UQ_Data_DataClass_Name ON exp.data(classId, name) WHERE classId IS NOT NULL; - -ALTER TABLE exp.data ALTER COLUMN cpastype nvarchar(300); - -ALTER TABLE exp.Data ADD LastIndexed DATETIME NULL; --- Issue 35817 - widen column to allow for longer paths and file names -ALTER TABLE exp.Data ALTER COLUMN DataFileURL NVARCHAR(600); - -ALTER TABLE exp.data ADD ObjectId INT; -ALTER TABLE exp.data ALTER COLUMN objectid INT NOT NULL; -CREATE UNIQUE INDEX idx_data_objectid ON exp.data (objectid); - --- Most major file systems cap file lengths at 255 characters. Let's do the same -ALTER TABLE exp.data ALTER COLUMN Name NVARCHAR(255); - -/* - Make PropertyDescriptor consistent with OWL terms, and also work for storing NCI_Thesaurus concepts - - We're somewhat merging to concepts here. - - A PropertyDescriptor with no Domain is a concept (or a Class in OWL). - A PropertyDescriptor with a Domain describes a member of a type (or an ObjectProperty in OWL) -*/ -CREATE TABLE exp.PropertyDescriptor -( - PropertyId INT IDENTITY (1, 1) NOT NULL, - PropertyURI NVARCHAR (200) NOT NULL, - OntologyURI NVARCHAR (200) NULL, - Name NVARCHAR (200) NULL, - Description NTEXT NULL, - RangeURI NVARCHAR (200) NOT NULL DEFAULT ('http://www.w3.org/2001/XMLSchema#string'), - ConceptURI NVARCHAR (200) NULL, - Label NVARCHAR (200) NULL, - SearchTerms NVARCHAR (1000) NULL, - SemanticType NVARCHAR (200) NULL, - Format NVARCHAR (50) NULL, - Container ENTITYID NOT NULL, - Project ENTITYID NOT NULL, - - LookupContainer ENTITYID, - LookupSchema VARCHAR(50), - LookupQuery VARCHAR(50), - DefaultValueType NVARCHAR(50), - Hidden BIT NOT NULL DEFAULT 0, - MvEnabled BIT NOT NULL DEFAULT 0, - ImportAliases NVARCHAR(200), - URL NVARCHAR(200), - ShownInInsertView BIT NOT NULL DEFAULT 1, - ShownInUpdateView BIT NOT NULL DEFAULT 1, - ShownInDetailsView BIT NOT NULL DEFAULT 1, - Dimension BIT NOT NULL DEFAULT '0', - Measure BIT NOT NULL DEFAULT '0', - - CONSTRAINT PK_PropertyDescriptor PRIMARY KEY NONCLUSTERED (PropertyId), - CONSTRAINT UQ_PropertyDescriptor UNIQUE CLUSTERED (Project, PropertyURI), - CONSTRAINT UQ_PropertyURIContainer UNIQUE (PropertyURI, Container) -); -CREATE INDEX IX_PropertyDescriptor_Container ON exp.PropertyDescriptor(Container); - -ALTER TABLE exp.PropertyDescriptor ADD CreatedBy USERID NULL; -ALTER TABLE exp.PropertyDescriptor ADD Created DATETIME NULL; -ALTER TABLE exp.PropertyDescriptor ADD ModifiedBy USERID NULL; -ALTER TABLE exp.PropertyDescriptor ADD Modified DATETIME NULL; -ALTER TABLE exp.PropertyDescriptor ADD CONSTRAINT FK_PropertyDescriptor_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); -ALTER TABLE exp.PropertyDescriptor ADD FacetingBehaviorType NVARCHAR(40) NOT NULL DEFAULT 'AUTOMATIC'; -ALTER TABLE exp.PropertyDescriptor ADD Protected BIT NOT NULL DEFAULT '0'; -ALTER TABLE exp.PropertyDescriptor ALTER COLUMN lookupschema NVARCHAR(200); -ALTER TABLE exp.PropertyDescriptor ALTER COLUMN lookupquery NVARCHAR(200); -ALTER TABLE exp.PropertyDescriptor ADD ExcludeFromShifting BIT NOT NULL DEFAULT '0'; -ALTER TABLE exp.propertydescriptor ADD Scale INT NOT NULL DEFAULT 0; -ALTER TABLE exp.PropertyDescriptor ADD KeyVariable BIT NOT NULL DEFAULT '0'; -ALTER TABLE exp.PropertyDescriptor ADD DefaultScale NVARCHAR(40) NOT NULL DEFAULT 'LINEAR'; -ALTER TABLE exp.PropertyDescriptor ADD StorageColumnName NVARCHAR(100) NULL; -GO - -EXEC sp_rename 'exp.PropertyDescriptor.KeyVariable', 'RecommendedVariable', 'COLUMN'; - -ALTER TABLE exp.PropertyDescriptor ADD Phi NVARCHAR(20) NOT NULL DEFAULT 'NotPHI'; -GO - -EXEC core.fn_dropifexists 'PropertyDescriptor', 'exp', 'COLUMN', 'Protected'; -GO - -ALTER TABLE exp.PropertyDescriptor ADD RedactedText NVARCHAR(450) NULL; -ALTER TABLE exp.PropertyDescriptor ADD mvIndicatorStorageColumnName NVARCHAR(120); -ALTER TABLE exp.PropertyDescriptor ADD TextExpression nvarchar(200) NULL -ALTER TABLE exp.PropertyDescriptor ALTER COLUMN PropertyURI NVARCHAR(300) NOT NULL; -ALTER TABLE exp.PropertyDescriptor DROP COLUMN OntologyURI; -ALTER TABLE exp.PropertyDescriptor DROP COLUMN SearchTerms; -ALTER TABLE exp.PropertyDescriptor DROP COLUMN SemanticType; -ALTER TABLE exp.PropertyDescriptor ADD PrincipalConceptCode NVARCHAR(50) NULL; -ALTER TABLE exp.PropertyDescriptor ADD SourceOntology NVARCHAR(20) NULL; -ALTER TABLE exp.PropertyDescriptor ADD ConceptImportColumn NVARCHAR(200) NULL; -ALTER TABLE exp.PropertyDescriptor ADD ConceptLabelColumn NVARCHAR(200) NULL; -ALTER TABLE exp.PropertyDescriptor ADD DerivationDataScope NVARCHAR(20) NULL; -ALTER TABLE exp.PropertyDescriptor ADD ConceptSubtree NVARCHAR(MAX) NULL; -ALTER TABLE exp.PropertyDescriptor ADD Scannable BIT NOT NULL DEFAULT 0; -GO - -CREATE TABLE exp.DataInput -( - DataId INT NOT NULL, - TargetApplicationId INT NOT NULL, - Role VARCHAR(50) NOT NULL, - - CONSTRAINT PK_DataInput PRIMARY KEY (DataId,TargetApplicationId), - CONSTRAINT FK_DataInputData_Data FOREIGN KEY (DataId) REFERENCES exp.Data (RowId), - CONSTRAINT FK_DataInput_ProtocolApplication FOREIGN KEY (TargetApplicationId) REFERENCES exp.ProtocolApplication (RowId) -); -CREATE INDEX IX_DataInput_TargetApplicationId ON exp.DataInput(TargetApplicationId); -CREATE INDEX IDX_DataInput_Role ON exp.DataInput(Role); - --- Add reference from DataInput to the ProtocolInputId that it corresponds to -ALTER TABLE exp.DataInput ADD ProtocolInputId INT NULL; - -CREATE INDEX IX_DataInput_ProtocolInputId ON exp.DataInput (ProtocolInputId); - -CREATE TABLE exp.Material -( - RowId INT NOT NULL, - LSID LSIDtype NOT NULL, - Name NVARCHAR (200) NULL, - CpasType NVARCHAR (200) NULL, - SourceApplicationId INT NULL, - RunId INT NULL, - Created DATETIME NOT NULL, - Container EntityId NOT NULL, - - CreatedBy INT, - ModifiedBy INT, - Modified DATETIME, - LastIndexed DATETIME, - - CONSTRAINT PK_Material PRIMARY KEY NONCLUSTERED (RowId), - CONSTRAINT UQ_Material_LSID UNIQUE (LSID), - CONSTRAINT FK_Material_ExperimentRun FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId), - CONSTRAINT FK_Material_ProtocolApplication FOREIGN KEY (SourceApplicationID) REFERENCES exp.ProtocolApplication (RowId), - CONSTRAINT FK_Material_Containers FOREIGN KEY (Container) REFERENCES core.Containers (EntityId) -); -CREATE CLUSTERED INDEX IX_CL_Material_RunId ON exp.Material(RunId); -CREATE INDEX IX_Material_Container ON exp.Material(Container); -CREATE INDEX IX_Material_SourceApplicationId ON exp.Material(SourceApplicationId); -CREATE INDEX IX_Material_CpasType ON exp.Material(CpasType); -CREATE INDEX IDX_Material_LSID ON exp.Material(LSID); - -EXECUTE core.fn_dropifexists 'material', 'exp', 'INDEX', 'idx_material_AK'; - -ALTER TABLE exp.material ALTER COLUMN name NVARCHAR(200) NOT NULL; - -CREATE UNIQUE INDEX idx_material_AK ON exp.material (container, cpastype, name) WHERE cpastype IS NOT NULL; -GO - -ALTER TABLE exp.material ADD description NVARCHAR(4000); - -ALTER TABLE exp.material ADD objectid INT; -GO - -ALTER TABLE exp.material ALTER COLUMN objectid INT NOT NULL; -GO - -CREATE UNIQUE INDEX idx_material_objectid ON exp.material (objectid); -GO - -ALTER TABLE exp.Material ADD RootMaterialLSID LSIDtype NULL; -ALTER TABLE exp.Material ADD AliquotedFromLSID LSIDtype NULL; -GO - -ALTER TABLE exp.Material ADD SampleState INT; -GO -ALTER TABLE exp.Material ADD CONSTRAINT FK_Material_SampleState FOREIGN KEY (SampleState) REFERENCES core.DataStates (RowId); - -ALTER TABLE exp.Material ADD RecomputeRollup BIT NULL CONSTRAINT DF_recomputeRollup DEFAULT(0); -ALTER TABLE exp.Material ADD AliquotCount INT NULL; -ALTER TABLE exp.Material ADD AliquotVolume FLOAT NULL; -ALTER TABLE exp.Material ADD AliquotUnit NVARCHAR(10) NULL; -GO - -CREATE INDEX IDX_exp_material_recompute ON exp.Material (container, rowid, lsid) WHERE RecomputeRollup=1; - -ALTER TABLE exp.Material ADD MaterialSourceId INT NULL; -GO -CREATE INDEX IDX_material_name_sourceid ON exp.Material (name, materialSourceId); -GO - -ALTER TABLE exp.Material ADD MaterialExpDate DATETIME NULL; - -ALTER TABLE exp.Material ADD StoredAmount DOUBLE PRECISION; -ALTER TABLE exp.Material ADD Units NVARCHAR(20); -GO - -EXEC core.fn_dropifexists 'Material', 'exp', 'INDEX', 'IDX_exp_material_recompute'; - -EXEC core.fn_dropifexists 'Material', 'exp', 'CONSTRAINT', 'DF_recomputeRollup'; - -ALTER TABLE exp.Material DROP COLUMN RecomputeRollup; - -ALTER TABLE exp.Material ADD AvailableAliquotCount INT NULL; -ALTER TABLE exp.Material ADD AvailableAliquotVolume FLOAT NULL; - -ALTER TABLE exp.material ALTER COLUMN rootmateriallsid LSIDtype NOT NULL; - -CREATE INDEX uq_material_rootlsid on exp.material (rootmateriallsid); - --- this is duplicative of constraint uq_material_lsid -EXEC core.fn_dropifexists 'material', 'exp', 'INDEX', 'idx_material_lsid'; - --- Add new "RootMaterialRowId" column -ALTER TABLE exp.Material ADD rootmaterialrowid INTEGER NULL; -GO - --- Add NOT NULL constraint to "RootMaterialRowId" -ALTER TABLE exp.Material ALTER COLUMN rootmaterialrowid INTEGER NOT NULL; -GO - --- Add FK on "RootMaterialRowId" --- See exp-23.012-23.013.sql --- ALTER TABLE exp.Material ADD CONSTRAINT FK_Material_RootMaterialRowId --- FOREIGN KEY (RootMaterialRowId) REFERENCES exp.Material (RowId); --- GO - -CREATE INDEX ix_material_rootmaterialrowid ON exp.Material (rootmaterialrowid); -GO - --- Remove the "RootMaterialLSID" column -EXEC core.fn_dropifexists 'material', 'exp', 'INDEX', 'uq_material_rootlsid'; -EXEC core.fn_dropifexists 'material', 'exp', 'COLUMN', 'rootmateriallsid'; - --- It is possible for parent samples of aliquots to be moved to a subfolder where upon deletion --- of the subfolder we need to delete the parent sample but the aliquot still exists. -EXEC core.fn_dropifexists 'material', 'exp', 'constraint', 'FK_Material_RootMaterialRowId'; -CREATE TABLE exp.MaterialInput -( - MaterialId INT NOT NULL, - TargetApplicationId INT NOT NULL, - Role VARCHAR(50) NOT NULL, - - CONSTRAINT PK_MaterialInput PRIMARY KEY (MaterialId, TargetApplicationId), - CONSTRAINT FK_MaterialInput_Material FOREIGN KEY (MaterialId) REFERENCES exp.Material (RowId), - CONSTRAINT FK_MaterialInput_ProtocolApplication FOREIGN KEY (TargetApplicationId) REFERENCES exp.ProtocolApplication (RowId) -); -CREATE INDEX IX_MaterialInput_TargetApplicationId ON exp.MaterialInput(TargetApplicationId); -CREATE INDEX IDX_MaterialInput_Role ON exp.MaterialInput(Role); - --- Add reference from MaterialInput to the ProtocolInputId that it corresponds to -ALTER TABLE exp.MaterialInput ADD ProtocolInputId INT NULL; - -CREATE INDEX IX_MaterialInput_ProtocolInputId ON exp.MaterialInput (ProtocolInputId); - -CREATE TABLE exp.MaterialSource -( - RowId INT IDENTITY (1, 1) NOT NULL, - Name NVARCHAR(50) NOT NULL, - LSID LSIDtype NOT NULL, - MaterialLSIDPrefix NVARCHAR(200) NULL, - Description NTEXT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - Container EntityId NOT NULL, - - IdCol1 NVARCHAR(200) NULL, - IdCol2 NVARCHAR(200) NULL, - IdCol3 NVARCHAR(200) NULL, - ParentCol NVARCHAR(200) NULL - - CONSTRAINT PK_MaterialSource PRIMARY KEY (RowId), - CONSTRAINT UQ_MaterialSource_LSID UNIQUE (LSID), -); -CREATE INDEX IX_MaterialSource_Container ON exp.MaterialSource(Container); - -ALTER TABLE exp.MaterialSource ADD CONSTRAINT FK_MaterialSource_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); --- Change exp.MaterialSource.Name from VARCHAR(50) to VARCHAR(100). Going to 200 to match other experiment tables - -- hits limits with domain URIs, etc -ALTER TABLE exp.MaterialSource ALTER COLUMN Name NVARCHAR(100); - -ALTER TABLE exp.MaterialSource ADD NameExpression NVARCHAR(200) NULL; - -ALTER TABLE exp.materialsource ALTER COLUMN nameexpression NVARCHAR(500); - -ALTER TABLE exp.MaterialSource ADD LastIndexed DATETIME NULL; - -ALTER TABLE exp.MaterialSource ADD MaterialParentImportAliasMap NVARCHAR(4000) NULL; - -ALTER TABLE exp.MaterialSource ADD LabelColor NVARCHAR(7) NULL; - -ALTER TABLE exp.MaterialSource ADD MetricUnit NVARCHAR(10) NULL; -GO - -ALTER TABLE exp.MaterialSource ADD AutoLinkTargetContainer ENTITYID NULL; - -ALTER TABLE exp.MaterialSource ADD AutoLinkCategory NVARCHAR(200) NULL; - -ALTER TABLE exp.MaterialSource ADD AliquotNameExpression NVARCHAR(200) NULL; - -ALTER TABLE exp.MaterialSource ADD Category NVARCHAR(20) NULL; - -EXEC core.fn_dropifexists 'materialsource', 'exp', 'CONSTRAINT', 'UQ_MaterialSource_Container_Name'; - -CREATE TABLE exp.Object -( - ObjectId INT IDENTITY(1,1) NOT NULL, - Container ENTITYID NOT NULL, - ObjectURI LSIDType NOT NULL, - OwnerObjectId INT NULL, - - CONSTRAINT PK_Object PRIMARY KEY NONCLUSTERED (ObjectId), - CONSTRAINT FK_Object_Object FOREIGN KEY (OwnerObjectId) REFERENCES exp.Object (ObjectId), - CONSTRAINT UQ_Object UNIQUE (ObjectURI), - CONSTRAINT FK_Object_Containers FOREIGN KEY (Container) REFERENCES core.Containers (EntityId) -); -CREATE CLUSTERED INDEX IDX_Object_ContainerOwnerObjectId ON exp.Object (Container, OwnerObjectId, ObjectId); -CREATE INDEX IX_Object_OwnerObjectId ON exp.Object(OwnerObjectId); - -ALTER TABLE exp.material ADD CONSTRAINT FK_Material_Lsid FOREIGN KEY (lsid) REFERENCES exp.object (objecturi); -ALTER TABLE exp.experimentrun ADD CONSTRAINT FK_ExperimentRun_Lsid FOREIGN KEY (lsid) REFERENCES exp.object (objecturi); -ALTER TABLE exp.material ADD CONSTRAINT FK_Material_ObjectId FOREIGN KEY (objectid) REFERENCES exp.object (objectid); -ALTER TABLE exp.experimentrun ADD CONSTRAINT FK_ExperimentRun_ObjectId FOREIGN KEY (objectid) REFERENCES exp.object (objectid); -GO - --- add constraints for lsid -> exp.object -ALTER TABLE exp.data ADD CONSTRAINT FK_Data_Lsid FOREIGN KEY (lsid) REFERENCES exp.object (objecturi); --- add constraints for objectid -> exp.object -ALTER TABLE exp.data ADD CONSTRAINT FK_Data_ObjectId FOREIGN KEY (objectid) REFERENCES exp.object (objectid); - --- todo this index is in pqsql script. Needed here? --- CREATE INDEX IDX_MaterialInput_TargetApplicationId ON exp.MaterialInput(TargetApplicationId); - -CREATE TABLE exp.ObjectProperty -( - ObjectId INT NOT NULL, -- FK exp.Object - PropertyId INT NOT NULL, -- FK exp.PropertyDescriptor - TypeTag CHAR(1) NOT NULL, -- s string, f float, d datetime, t text - FloatValue FLOAT NULL, - DateTimeValue DATETIME NULL, - StringValue NVARCHAR(4000) NULL, - MvIndicator NVARCHAR(50) NULL, - - CONSTRAINT PK_ObjectProperty PRIMARY KEY CLUSTERED (ObjectId, PropertyId), - CONSTRAINT FK_ObjectProperty_Object FOREIGN KEY (ObjectId) REFERENCES exp.Object (ObjectId), - CONSTRAINT FK_ObjectProperty_PropertyDescriptor FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor (PropertyId) -); -CREATE INDEX IDX_ObjectProperty_PropertyId ON exp.ObjectProperty(PropertyId); - -CREATE TABLE exp.ProtocolAction -( - RowId INT IDENTITY (10, 10) NOT NULL, - ParentProtocolId INT NOT NULL, - ChildProtocolId INT NOT NULL, - Sequence INT NOT NULL, - - CONSTRAINT PK_ProtocolAction PRIMARY KEY (RowId), - CONSTRAINT UQ_ProtocolAction UNIQUE (ParentProtocolId, ChildProtocolId, Sequence), - CONSTRAINT FK_ProtocolAction_Parent_Protocol FOREIGN KEY (ParentProtocolId) REFERENCES exp.Protocol (RowId), - CONSTRAINT FK_ProtocolAction_Child_Protocol FOREIGN KEY (ChildProtocolId) REFERENCES exp.Protocol (RowId) -); -CREATE INDEX IX_ProtocolAction_ChildProtocolId ON exp.ProtocolAction(ChildProtocolId); - -CREATE TABLE exp.ProtocolActionPredecessor -( - ActionId INT NOT NULL, - PredecessorId INT NOT NULL, - - CONSTRAINT PK_ActionPredecessor PRIMARY KEY (ActionId, PredecessorId), - CONSTRAINT FK_ActionPredecessor_Action_ProtocolAction FOREIGN KEY (ActionId) REFERENCES exp.ProtocolAction (RowId), - CONSTRAINT FK_ActionPredecessor_Predecessor_ProtocolAction FOREIGN KEY (PredecessorId) REFERENCES exp.ProtocolAction (RowId) -); -CREATE INDEX IX_ProtocolActionPredecessor_PredecessorId ON exp.ProtocolActionPredecessor(PredecessorId); - -CREATE TABLE exp.ProtocolParameter -( - RowId INT IDENTITY (1, 1) NOT NULL, - ProtocolId INT NOT NULL, - Name NVARCHAR (200) NULL, - ValueType NVARCHAR(50) NULL, - StringValue NVARCHAR (4000) NULL, - IntegerValue INT NULL, - DoubleValue FLOAT NULL, - DateTimeValue DATETIME NULL, - OntologyEntryURI NVARCHAR (200) NULL, - - CONSTRAINT PK_ProtocolParameter PRIMARY KEY (RowId), - CONSTRAINT UQ_ProtocolParameter_Ord UNIQUE (ProtocolId, Name), - CONSTRAINT FK_ProtocolParameter_Protocol FOREIGN KEY (ProtocolId) REFERENCES exp.Protocol (RowId) -); -CREATE INDEX IX_ProtocolParameter_ProtocolId ON exp.ProtocolParameter(ProtocolId); - -CREATE TABLE exp.ProtocolApplicationParameter -( - RowId INT IDENTITY (1, 1) NOT NULL, - ProtocolApplicationId INT NOT NULL, - Name NVARCHAR (200) NULL, - ValueType NVARCHAR(50) NULL, - StringValue NTEXT NULL, - IntegerValue INT NULL, - DoubleValue FLOAT NULL, - DateTimeValue DATETIME NULL, - OntologyEntryURI NVARCHAR (200) NULL, - - CONSTRAINT PK_ProtocolAppParam PRIMARY KEY (RowId), - CONSTRAINT UQ_ProtocolAppParam_Ord UNIQUE (ProtocolApplicationId, Name), - CONSTRAINT FK_ProtocolAppParam_ProtocolApp FOREIGN KEY (ProtocolApplicationId) REFERENCES exp.ProtocolApplication (RowId) -); -CREATE INDEX IX_ProtocolApplicationParameter_AppId ON exp.ProtocolApplicationParameter(ProtocolApplicationId); - -CREATE TABLE exp.DomainDescriptor -( - DomainId INT IDENTITY (1, 1) NOT NULL, - Name NVARCHAR (200) NULL, - DomainURI NVARCHAR (200) NOT NULL, - Description NTEXT NULL, - Container ENTITYID NOT NULL, - Project ENTITYID NOT NULL, - StorageTableName NVARCHAR(100), - StorageSchemaName NVARCHAR(100), - - CONSTRAINT PK_DomainDescriptor PRIMARY KEY NONCLUSTERED (DomainId), - CONSTRAINT UQ_DomainDescriptor UNIQUE CLUSTERED (Project, DomainURI), - CONSTRAINT UQ_DomainURIContainer UNIQUE (DomainURI, Container) -); -CREATE INDEX IX_DomainDescriptor_Container ON exp.DomainDescriptor(Container); - --- Add some FKs -ALTER TABLE exp.DomainDescriptor ADD CONSTRAINT FK_DomainDescriptor_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); -ALTER TABLE exp.DomainDescriptor DROP CONSTRAINT uq_domainuricontainer; -ALTER TABLE exp.DomainDescriptor DROP CONSTRAINT uq_domaindescriptor; - -ALTER TABLE exp.DomainDescriptor ADD CONSTRAINT uq_domaindescriptor UNIQUE (DomainURI, Project); - -ALTER TABLE exp.DomainDescriptor ADD _ts ROWVERSION; -ALTER TABLE exp.DomainDescriptor ADD ModifiedBy USERID; -ALTER TABLE exp.DomainDescriptor ADD Modified DATETIME DEFAULT GETDATE(); -GO - -ALTER TABLE exp.DomainDescriptor ADD TemplateInfo NVARCHAR(4000) NULL; -ALTER TABLE exp.DomainDescriptor ALTER COLUMN DomainURI NVARCHAR(300) NOT NULL; -ALTER TABLE exp.DomainDescriptor ADD SystemFieldConfig NVARCHAR(MAX) NULL; - -CREATE TABLE exp.PropertyDomain -( - PropertyId INT NOT NULL, - DomainId INT NOT NULL, - Required BIT NOT NULL DEFAULT 0, - SortOrder INT NOT NULL DEFAULT 0, - - CONSTRAINT PK_PropertyDomain PRIMARY KEY CLUSTERED (PropertyId, DomainId), - CONSTRAINT FK_PropertyDomain_Property FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor (PropertyId), - CONSTRAINT FK_PropertyDomain_DomainDescriptor FOREIGN KEY (DomainId) REFERENCES exp.DomainDescriptor (DomainId), -); -CREATE INDEX IX_PropertyDomain_DomainId ON exp.PropertyDomain(DomainID); - -CREATE TABLE exp.RunList -( - ExperimentId INT NOT NULL, - ExperimentRunId INT NOT NULL, - - CONSTRAINT PK_RunList PRIMARY KEY (ExperimentId, ExperimentRunId), - CONSTRAINT FK_RunList_ExperimentId FOREIGN KEY (ExperimentId) REFERENCES exp.Experiment(RowId), - CONSTRAINT FK_RunList_ExperimentRunId FOREIGN KEY (ExperimentRunId) REFERENCES exp.ExperimentRun(RowId) -); -CREATE INDEX IX_RunList_ExperimentRunId ON exp.RunList(ExperimentRunId); - -ALTER TABLE exp.RunList ADD CreatedBy INT; -ALTER TABLE exp.RunList ADD Created DATETIME; - -CREATE TABLE exp.list -( - RowId INT IDENTITY (1, 1) NOT NULL, - EntityId UNIQUEIDENTIFIER NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - - Container UNIQUEIDENTIFIER NOT NULL, - Name NVARCHAR(64) NOT NULL, - DomainId INT NOT NULL, - KeyName NVARCHAR(64) NOT NULL, - KeyType VARCHAR(64) NOT NULL, - Description NTEXT, - TitleColumn NVARCHAR(200), - DiscussionSetting SMALLINT NOT NULL DEFAULT 0, - AllowDelete BIT NOT NULL DEFAULT 1, - AllowUpload BIT NOT NULL DEFAULT 1, - AllowExport BIT NOT NULL DEFAULT 1, - IndexMetaData BIT NOT NULL DEFAULT 1, - - CONSTRAINT PK_List PRIMARY KEY(RowId), - CONSTRAINT UQ_LIST UNIQUE(Container, Name), - CONSTRAINT FK_List_DomainId FOREIGN KEY (DomainId) REFERENCES exp.DomainDescriptor(DomainId) -); -CREATE INDEX IDX_List_DomainId ON exp.List(DomainId); - -ALTER TABLE exp.List ADD CONSTRAINT FK_List_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); --- Use prefix naming to better match new field names -EXEC sp_rename 'exp.List.IndexMetaData', 'MetaDataIndex', 'COLUMN'; - -ALTER TABLE exp.list ADD EntireListIndex BIT NOT NULL DEFAULT 0; -ALTER TABLE exp.list ADD EntireListTitleSetting INT NOT NULL DEFAULT 0; -ALTER TABLE exp.list ADD EntireListTitleTemplate NVARCHAR(1000) NULL; -ALTER TABLE exp.list ADD EntireListBodyTemplate NVARCHAR(1000) NULL; -ALTER TABLE exp.list ADD EntireListBodySetting INT NOT NULL DEFAULT 0; - -ALTER TABLE exp.list ADD EachItemIndex BIT NOT NULL DEFAULT 0; -ALTER TABLE exp.list ADD EachItemTitleSetting INT NOT NULL DEFAULT 0; -ALTER TABLE exp.list ADD EachItemTitleTemplate NVARCHAR(1000) NULL; -ALTER TABLE exp.list ADD EachItemBodySetting INT NOT NULL DEFAULT 0; -ALTER TABLE exp.list ADD EachItemBodyTemplate NVARCHAR(1000) NULL; - -ALTER TABLE exp.List ADD LastIndexed DATETIME NULL; - --- Merge the "metadata only" and "entire list data" settings, migrating them to a single boolean (EntireListIndex) plus --- a setting denoting what to index (EntireListIndexSetting = metadata only (0), item data only (1), or both (2)) - -ALTER TABLE exp.List ADD EntireListIndexSetting INT NOT NULL DEFAULT 0; -- Metadata only, the default -GO - --- Must drop default constraint before dropping column -EXEC core.fn_dropifexists @objname='List', @objschema='exp', @objtype='DEFAULT', @subobjname='MetaDataIndex' - -ALTER TABLE exp.List DROP COLUMN MetaDataIndex; - -ALTER TABLE exp.List DROP CONSTRAINT PK_List; -ALTER TABLE exp.List ADD CONSTRAINT UQ_RowId UNIQUE (RowId); --- Now add ListId column... -ALTER TABLE exp.List ADD ListId INT NOT NULL; -GO - --- ...and create the new PK (Container, ListId) -ALTER TABLE exp.List ADD CONSTRAINT PK_List PRIMARY KEY (Container, ListId); - -EXEC core.fn_dropifexists 'list', 'exp', 'CONSTRAINT', 'UQ_RowId'; -EXEC core.fn_dropifexists 'list', 'exp', 'COLUMN', 'rowid'; - -ALTER TABLE exp.list ADD FileAttachmentIndex BIT CONSTRAINT DF__list__FileAttachmentIndex DEFAULT 0 NOT NULL; -GO - -ALTER TABLE exp.List ADD Category NVARCHAR(20) NULL; - -ALTER TABLE exp.list ALTER COLUMN Name NVARCHAR(200); -GO - --- These columns have been unused for years. https://github.com/LabKey/platform/pull/4549 cleaned up all code references. --- Use fb_dropIfExists() to drop default constraint before dropping each column. -EXEC core.fn_dropifexists 'List', 'exp', 'COLUMN', 'EntireListTitleSetting'; -EXEC core.fn_dropifexists 'List', 'exp', 'COLUMN', 'EachItemTitleSetting'; - -CREATE TABLE exp.ConditionalFormat -( - RowId INT IDENTITY(1,1) NOT NULL, - SortOrder INT NOT NULL, - PropertyId INT NOT NULL, - Filter NVARCHAR(500) NOT NULL, - Bold BIT NOT NULL, - Italic BIT NOT NULL, - Strikethrough BIT NOT NULL, - TextColor NVARCHAR(10), - BackgroundColor NVARCHAR(10), - - CONSTRAINT PK_ConditionalFormat_RowId PRIMARY KEY (RowId), - CONSTRAINT FK_ConditionalFormat_PropertyId FOREIGN KEY (PropertyId) REFERENCES exp.PropertyDescriptor (PropertyId), - CONSTRAINT UQ_ConditionalFormat_PropertyId_SortOrder UNIQUE (PropertyId, SortOrder) -); -CREATE INDEX IDX_ConditionalFormat_PropertyId ON exp.ConditionalFormat(PropertyId); -GO - -CREATE TABLE exp.AssayQCFlag -( - RowId INT IDENTITY (1, 1) NOT NULL, - RunId INT NOT NULL, - FlagType VARCHAR(40) NOT NULL, - Description TEXT NULL, - Comment TEXT NULL, - Enabled BIT NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL -); - -ALTER TABLE exp.AssayQCFlag ADD CONSTRAINT PK_AssayQCFlag PRIMARY KEY (RowId); - -ALTER TABLE exp.AssayQCFlag ADD CONSTRAINT FK_AssayQCFlag_EunId FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId); - -CREATE INDEX IX_AssayQCFlag_RunId ON exp.AssayQCFlag(RunId); - -ALTER TABLE exp.AssayQCFlag ADD IntKey1 INT NULL; -ALTER TABLE exp.AssayQCFlag ADD IntKey2 INT NULL; - -CREATE INDEX IX_AssayQCFlag_IntKeys ON exp.AssayQCFlag(IntKey1, IntKey2); - -ALTER TABLE exp.AssayQCFlag ADD Key1 NVARCHAR(50); -ALTER TABLE exp.AssayQCFlag ADD Key2 NVARCHAR(50); - -CREATE INDEX IX_AssayQCFlag_Keys ON exp.AssayQCFlag(Key1, Key2); - -CREATE TABLE exp.DataClass -( - RowId INT IDENTITY(1,1) NOT NULL, - Name NVARCHAR(200) NOT NULL, - LSID LSIDtype NOT NULL, - Container EntityId NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - Description NTEXT NULL, - MaterialSourceId INT NULL, - NameExpression NVARCHAR(200) NULL, - - CONSTRAINT PK_DataClass PRIMARY KEY (RowId), - CONSTRAINT UQ_DataClass_LSID UNIQUE (LSID), - CONSTRAINT UQ_DataClass_Container_Name UNIQUE (Container, Name), - - CONSTRAINT FK_DataClass_Container FOREIGN KEY (Container) REFERENCES core.Containers(EntityId), - CONSTRAINT FK_DataClass_MaterialSource FOREIGN KEY (MaterialSourceId) REFERENCES exp.MaterialSource (RowId) -); -CREATE INDEX IX_DataClass_Container ON exp.DataClass(Container); - -ALTER TABLE exp.data ADD CONSTRAINT FK_Data_DataClass FOREIGN KEY (classId) REFERENCES exp.DataClass (rowid); - -ALTER TABLE exp.dataclass ALTER COLUMN nameexpression NVARCHAR(500); - -ALTER TABLE exp.DataClass ADD Category NVARCHAR(20) NULL; - -ALTER TABLE exp.DataClass ADD LastIndexed DATETIME NULL; - -ALTER TABLE exp.DataClass ADD dataparentimportaliasmap NVARCHAR(4000) NULL; - -CREATE TABLE exp.Alias -( - RowId INT IDENTITY (1, 1) NOT NULL, - Created DATETIME, - CreatedBy INT, - Modified DATETIME, - ModifiedBy INT, - - Name NVARCHAR(500) NOT NULL, - - CONSTRAINT PK_Alias PRIMARY KEY (RowId), - CONSTRAINT UQ_Alias_Name UNIQUE (Name) -); - -CREATE INDEX IX_Alias_Name ON exp.Alias(Name); - -CREATE TABLE exp.DataAliasMap -( - LSID LSIDtype NOT NULL, - Alias INT NOT NULL, - Container EntityId NOT NULL, - - CONSTRAINT PK_DataAliasMap PRIMARY KEY (LSID, Alias), - CONSTRAINT FK_DataAlias_RowId FOREIGN KEY (Alias) REFERENCES exp.Alias(RowId) -); - -ALTER TABLE exp.DataAliasMap ADD CONSTRAINT FK_DataAlias_LSID FOREIGN KEY (LSID) REFERENCES exp.Data(LSID); -CREATE INDEX IX_DataAliasMap ON exp.DataAliasMap(LSID, Alias, Container); - -CREATE TABLE exp.MaterialAliasMap -( - LSID LSIDtype NOT NULL, - Alias INT NOT NULL, - Container EntityId NOT NULL, - - CONSTRAINT PK_MaterialAliasMap PRIMARY KEY (LSID, Alias), - CONSTRAINT FK_MaterialAlias_RowId FOREIGN KEY (Alias) REFERENCES exp.Alias(RowId) -); - -ALTER TABLE exp.MaterialAliasMap ADD CONSTRAINT FK_MaterialAlias_LSID FOREIGN KEY (LSID) REFERENCES exp.Material(LSID); -CREATE INDEX IX_MaterialAliasMap ON exp.MaterialAliasMap(LSID, Alias, Container); - -CREATE TABLE exp.Edge -( - FromObjectId INT NOT NULL, --- FromLsid LSIDtype NOT NULL, - ToObjectId INT NOT NULL, --- ToLsid LSIDtype NOT NULL, - RunId INT NOT NULL, - - CONSTRAINT FK_Edge_From_Object FOREIGN KEY (FromObjectId) REFERENCES exp.object (objectid), - CONSTRAINT FK_Edge_To_Object FOREIGN KEY (ToObjectId) REFERENCES exp.object (objectid), - CONSTRAINT FK_Edge_RunId_Run FOREIGN KEY (RunId) REFERENCES exp.ExperimentRun (RowId), --- for query performance - CONSTRAINT UQ_Edge_FromTo_RunId UNIQUE (FromObjectId, ToObjectId, RunId), - CONSTRAINT UQ_Edge_ToFrom_RunId UNIQUE (ToObjectId, FromObjectId, RunId) -); -GO - -ALTER TABLE exp.Edge DROP CONSTRAINT UQ_Edge_FromTo_RunId; -ALTER TABLE exp.Edge DROP CONSTRAINT UQ_Edge_ToFrom_RunId; - -ALTER TABLE exp.Edge ALTER COLUMN RunId INT NULL; - -ALTER TABLE exp.Edge ADD SourceId INT NULL; -ALTER TABLE exp.Edge ADD SourceKey NVARCHAR(200) NULL; - -ALTER TABLE exp.Edge ADD CONSTRAINT FK_Edge_SourceId_Object FOREIGN KEY (SourceId) REFERENCES exp.Object (Objectid); -ALTER TABLE exp.Edge ADD CONSTRAINT UQ_Edge_FromTo_RunId_SourceId_SourceKey UNIQUE (FromObjectId, ToObjectId, RunId, SourceId, SourceKey); - -CREATE INDEX IX_Edge_ToObjectId ON exp.Edge(ToObjectId); -CREATE INDEX IX_Edge_SourceId ON exp.Edge(SourceId); -GO - -CREATE INDEX IDX_Edge_RunId ON exp.Edge(RunId); - -CREATE TABLE exp.ProtocolInput -( - RowId INT IDENTITY (1,1) NOT NULL, - Name NVARCHAR(300) NOT NULL, - LSID LSIDtype NOT NULL, - ProtocolId INT NOT NULL, - Input BIT NOT NULL, - - -- One of 'Material' or 'Data' - ObjectType NVARCHAR(8) NOT NULL, - - -- DataClassId may be non-null when ObjectType='Data' - DataClassId INT NULL, - -- MaterialSourceId may be non-null when ObjectType='Material' - MaterialSourceId INT NULL, - - CriteriaName NVARCHAR(50) NULL, - CriteriaConfig NTEXT NULL, - MinOccurs INT NOT NULL, - MaxOccurs INT NULL, - - CONSTRAINT PK_ProtocolInput_RowId PRIMARY KEY (RowId), - CONSTRAINT FK_ProtocolInput_ProtocolId FOREIGN KEY (ProtocolId) REFERENCES exp.Protocol (RowId), - CONSTRAINT FK_ProtocolInput_DataClassId FOREIGN KEY (DataClassId) REFERENCES exp.DataClass (RowId), - CONSTRAINT FK_ProtocolInput_MaterialSourceId FOREIGN KEY (MaterialSourceId) REFERENCES exp.MaterialSource (RowId) -); - -CREATE INDEX IX_ProtocolInput_ProtocolId ON exp.ProtocolInput (ProtocolId); -CREATE INDEX IX_ProtocolInput_DataClassId ON exp.ProtocolInput (DataClassId); -CREATE INDEX IX_ProtocolInput_MaterialSourceId ON exp.ProtocolInput (MaterialSourceId); - -ALTER TABLE exp.MaterialInput ADD CONSTRAINT FK_MaterialInput_ProtocolInput FOREIGN KEY (ProtocolInputId) REFERENCES exp.ProtocolInput (RowId); - -ALTER TABLE exp.DataInput ADD CONSTRAINT FK_DataInput_ProtocolInput FOREIGN KEY (ProtocolInputId) REFERENCES exp.ProtocolInput (RowId); - -CREATE TABLE exp.PropertyValidator -( - RowId int identity(1,1) not null, - Name NVARCHAR(50) not null, - Description NVARCHAR(200), - TypeURI NVARCHAR(200) not null, - Expression NVARCHAR(MAX), - ErrorMessage NVARCHAR(MAX), - Properties NVARCHAR(MAX), - Container entityid not null constraint fk_pv_container references core.containers (entityid), - PropertyId int not null constraint fk_pv_descriptor references exp.propertydescriptor, - constraint pk_propertyvalidator primary key (container, propertyid, rowid) -); -GO - -CREATE INDEX ix_propertyvalidator_propertyid on exp.PropertyValidator(PropertyId); - -CREATE TABLE exp.ObjectLegacyNames -( - RowId INT IDENTITY (1, 1) NOT NULL, - ObjectId INT NOT NULL, - ObjectType NVARCHAR(20) NOT NULL, - Name NVARCHAR(200) NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - - CONSTRAINT PK_ObjectLegacyNames PRIMARY KEY (RowId) -); -GO - -CREATE TABLE exp.DataTypeExclusion -( - RowId INT IDENTITY (1, 1) NOT NULL, - DataTypeRowId INT NOT NULL, - DataType NVARCHAR(20) NOT NULL, - ExcludedContainer EntityId NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - - CONSTRAINT PK_DataTypeExclusion PRIMARY KEY (RowId), - CONSTRAINT UQ_DataTypeExclusion_LSID UNIQUE (DataTypeRowId, DataType, ExcludedContainer) -); -GO - --- Create procedures used by Ontology Manager -CREATE PROCEDURE exp.getObjectProperties(@container ENTITYID, @lsid LSIDType) AS -BEGIN - SELECT * FROM exp.ObjectPropertiesView - WHERE Container = @container AND ObjectURI = @lsid -END -GO - -CREATE PROCEDURE exp.ensureObject(@container ENTITYID, @lsid LSIDType, @ownerObjectId INTEGER) AS -BEGIN - DECLARE @objectid AS INTEGER - SET NOCOUNT ON - BEGIN TRANSACTION - SELECT @objectid = ObjectId FROM exp.Object WHERE Container=@container AND ObjectURI=@lsid - IF (@objectid IS NULL) - BEGIN - INSERT INTO exp.Object (Container, ObjectURI, OwnerObjectId) VALUES (@container, @lsid, @ownerObjectId) - SELECT @objectid = @@identity - END - COMMIT - SELECT @objectid -END -GO - -CREATE PROCEDURE exp.deleteObject(@container ENTITYID, @lsid LSIDType) AS -BEGIN - SET NOCOUNT ON - DECLARE @objectid INTEGER - SELECT @objectid = ObjectId FROM exp.Object WHERE Container=@container AND ObjectURI=@lsid - IF (@objectid IS NULL) - RETURN - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE ObjectId IN - (SELECT ObjectId FROM exp.Object WHERE OwnerObjectId = @objectid) - DELETE exp.ObjectProperty WHERE ObjectId = @objectid - DELETE exp.Object WHERE OwnerObjectId = @objectid - DELETE exp.Object WHERE ObjectId = @objectid - COMMIT -END -GO - --- internal methods -CREATE PROCEDURE exp._insertFloatProperty(@objectid INTEGER, @propid INTEGER, @float FLOAT) AS -BEGIN - IF (@propid IS NULL OR @objectid IS NULL) RETURN - INSERT INTO exp.ObjectProperty (ObjectId, PropertyId, TypeTag, FloatValue) - VALUES (@objectid, @propid, 'f', @float) -END -GO - -CREATE PROCEDURE exp._insertDateTimeProperty(@objectid INTEGER, @propid INTEGER, @datetime DATETIME) AS -BEGIN - IF (@propid IS NULL OR @objectid IS NULL) RETURN - INSERT INTO exp.ObjectProperty (ObjectId, PropertyId, TypeTag, DateTimeValue) - VALUES (@objectid, @propid, 'd', @datetime) -END -GO - -CREATE PROCEDURE exp._insertStringProperty(@objectid INTEGER, @propid INTEGER, @string VARCHAR(400)) AS -BEGIN - IF (@propid IS NULL OR @objectid IS NULL) RETURN - INSERT INTO exp.ObjectProperty (ObjectId, PropertyId, TypeTag, StringValue) - VALUES (@objectid, @propid, 's', @string) -END -GO - --- --- Set the same property on multiple objects (e.g. import a column of data) --- --- fast method for importing ObjectProperties (need to wrap with datalayer code) --- - -CREATE PROCEDURE exp.setFloatProperties(@propertyid INTEGER, - @objectid1 INTEGER, @float1 FLOAT, - @objectid2 INTEGER, @float2 FLOAT, - @objectid3 INTEGER, @float3 FLOAT, - @objectid4 INTEGER, @float4 FLOAT, - @objectid5 INTEGER, @float5 FLOAT, - @objectid6 INTEGER, @float6 FLOAT, - @objectid7 INTEGER, @float7 FLOAT, - @objectid8 INTEGER, @float8 FLOAT, - @objectid9 INTEGER, @float9 FLOAT, - @objectid10 INTEGER, @float10 FLOAT - ) AS -BEGIN - SET NOCOUNT ON - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE PropertyId=@propertyid AND ObjectId IN (@objectid1, @objectid2, @objectid3, @objectid4, @objectid5, @objectid6, @objectid7, @objectid8, @objectid9, @objectid10) - EXEC exp._insertFloatProperty @objectid1, @propertyid, @float1 - EXEC exp._insertFloatProperty @objectid2, @propertyid, @float2 - EXEC exp._insertFloatProperty @objectid3, @propertyid, @float3 - EXEC exp._insertFloatProperty @objectid4, @propertyid, @float4 - EXEC exp._insertFloatProperty @objectid5, @propertyid, @float5 - EXEC exp._insertFloatProperty @objectid6, @propertyid, @float6 - EXEC exp._insertFloatProperty @objectid7, @propertyid, @float7 - EXEC exp._insertFloatProperty @objectid8, @propertyid, @float8 - EXEC exp._insertFloatProperty @objectid9, @propertyid, @float9 - EXEC exp._insertFloatProperty @objectid10, @propertyid, @float10 - COMMIT -END -GO - -CREATE PROCEDURE exp.setStringProperties(@propertyid INTEGER, - @objectid1 INTEGER, @string1 VARCHAR(400), - @objectid2 INTEGER, @string2 VARCHAR(400), - @objectid3 INTEGER, @string3 VARCHAR(400), - @objectid4 INTEGER, @string4 VARCHAR(400), - @objectid5 INTEGER, @string5 VARCHAR(400), - @objectid6 INTEGER, @string6 VARCHAR(400), - @objectid7 INTEGER, @string7 VARCHAR(400), - @objectid8 INTEGER, @string8 VARCHAR(400), - @objectid9 INTEGER, @string9 VARCHAR(400), - @objectid10 INTEGER, @string10 VARCHAR(400) - ) AS -BEGIN - SET NOCOUNT ON - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE PropertyId=@propertyid AND ObjectId IN (@objectid1, @objectid2, @objectid3, @objectid4, @objectid5, @objectid6, @objectid7, @objectid8, @objectid9, @objectid10) - EXEC exp._insertStringProperty @objectid1, @propertyid, @string1 - EXEC exp._insertStringProperty @objectid2, @propertyid, @string2 - EXEC exp._insertStringProperty @objectid3, @propertyid, @string3 - EXEC exp._insertStringProperty @objectid4, @propertyid, @string4 - EXEC exp._insertStringProperty @objectid5, @propertyid, @string5 - EXEC exp._insertStringProperty @objectid6, @propertyid, @string6 - EXEC exp._insertStringProperty @objectid7, @propertyid, @string7 - EXEC exp._insertStringProperty @objectid8, @propertyid, @string8 - EXEC exp._insertStringProperty @objectid9, @propertyid, @string9 - EXEC exp._insertStringProperty @objectid10, @propertyid, @string10 - COMMIT -END -GO - -CREATE PROCEDURE exp.setDateTimeProperties(@propertyid INTEGER, - @objectid1 INTEGER, @datetime1 DATETIME, - @objectid2 INTEGER, @datetime2 DATETIME, - @objectid3 INTEGER, @datetime3 DATETIME, - @objectid4 INTEGER, @datetime4 DATETIME, - @objectid5 INTEGER, @datetime5 DATETIME, - @objectid6 INTEGER, @datetime6 DATETIME, - @objectid7 INTEGER, @datetime7 DATETIME, - @objectid8 INTEGER, @datetime8 DATETIME, - @objectid9 INTEGER, @datetime9 DATETIME, - @objectid10 INTEGER, @datetime10 DATETIME - ) AS -BEGIN - SET NOCOUNT ON - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE PropertyId=@propertyid AND ObjectId IN (@objectid1, @objectid2, @objectid3, @objectid4, @objectid5, @objectid6, @objectid7, @objectid8, @objectid9, @objectid10) - EXEC exp._insertDateTimeProperty @objectid1, @propertyid, @datetime1 - EXEC exp._insertDateTimeProperty @objectid2, @propertyid, @datetime2 - EXEC exp._insertDateTimeProperty @objectid3, @propertyid, @datetime3 - EXEC exp._insertDateTimeProperty @objectid4, @propertyid, @datetime4 - EXEC exp._insertDateTimeProperty @objectid5, @propertyid, @datetime5 - EXEC exp._insertDateTimeProperty @objectid6, @propertyid, @datetime6 - EXEC exp._insertDateTimeProperty @objectid7, @propertyid, @datetime7 - EXEC exp._insertDateTimeProperty @objectid8, @propertyid, @datetime8 - EXEC exp._insertDateTimeProperty @objectid9, @propertyid, @datetime9 - EXEC exp._insertDateTimeProperty @objectid10, @propertyid, @datetime10 - COMMIT -END -GO - -CREATE PROCEDURE exp.deleteObjectById(@container ENTITYID, @objectid INTEGER) AS -BEGIN - SET NOCOUNT ON - SELECT @objectid = ObjectId FROM exp.Object WHERE Container=@container AND ObjectId=@objectid - IF (@objectid IS NULL) - RETURN - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE ObjectId IN - (SELECT ObjectId FROM exp.Object WHERE OwnerObjectId = @objectid) - DELETE exp.ObjectProperty WHERE ObjectId = @objectid - DELETE exp.Object WHERE OwnerObjectId = @objectid - DELETE exp.Object WHERE ObjectId = @objectid - COMMIT -END -GO - -/* 24.xxx SQL scripts */ - -CREATE TABLE exp.MaterialIndexed -( - MaterialId INT NOT NULL, - LastIndexed DATETIME NOT NULL, - - CONSTRAINT PK_MaterialIndexing PRIMARY KEY (MaterialId), - CONSTRAINT FK_MaterialId FOREIGN KEY (MaterialId) REFERENCES exp.Material (RowId) ON DELETE CASCADE -); - -INSERT INTO exp.MaterialIndexed (MaterialId, LastIndexed) (SELECT RowId, LastIndexed FROM exp.Material WHERE LastIndexed IS NOT NULL); - -ALTER TABLE exp.Material DROP COLUMN LastIndexed; - - -CREATE TABLE exp.DataIndexed -( - DataId INT NOT NULL, - LastIndexed DATETIME NOT NULL, - - CONSTRAINT PK_DataIndexing PRIMARY KEY (DataId), - CONSTRAINT FK_DataId FOREIGN KEY (DataId) REFERENCES exp.Data (RowId) ON DELETE CASCADE -); - -INSERT INTO exp.DataIndexed (DataId, LastIndexed) (SELECT RowId, LastIndexed FROM exp.Data WHERE LastIndexed IS NOT NULL); - -ALTER TABLE exp.Data DROP COLUMN LastIndexed; - -CREATE TABLE exp.MaterialAncestors -( - RowId INT NOT NULL, - AncestorRowId INT NOT NULL, - AncestorTypeId VARCHAR(11), - - CONSTRAINT FK_MaterialAncestors_MaterialId FOREIGN KEY (RowId) REFERENCES exp.Material (RowId) ON DELETE CASCADE -); - -CREATE UNIQUE INDEX UQ_MaterialAncestors_AncestorTypeId_RowId ON exp.MaterialAncestors (AncestorTypeId, RowId); -CREATE INDEX IDX_MaterialAncestors_AncestorTypeId_RowId_AncestorRowId ON exp.MaterialAncestors (AncestorTypeId, RowId, AncestorRowId); - -CREATE TABLE exp.DataAncestors -( - RowId INT NOT NULL, - AncestorRowId INT NOT NULL, - AncestorTypeId VARCHAR(11), - - CONSTRAINT FK_DataAncestors_DataId FOREIGN KEY (RowId) REFERENCES exp.Data (RowId) ON DELETE CASCADE -); - -CREATE UNIQUE INDEX UQ_DataAncestors_AncestorTypeId_RowId ON exp.DataAncestors (AncestorTypeId, RowId); -CREATE INDEX IDX_DataAncestors_AncestorTypeId_RowId_AncestorRowId ON exp.DataAncestors (AncestorTypeId, RowId, AncestorRowId); - -DROP INDEX ix_material_cpastype on exp.material; -CREATE INDEX ix_material_cpastype ON exp.material (cpastype, rowid); diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.000-25.001.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.000-25.001.sql deleted file mode 100644 index 4828c7a2824..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.000-25.001.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- remove limit on stringvalue field -ALTER TABLE exp.ObjectProperty ALTER COLUMN StringValue NVARCHAR(MAX) NULL; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.001-25.002.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.001-25.002.sql deleted file mode 100644 index ed2f281d8bc..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.001-25.002.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- We don't expect storage column names this large, but this allows us to remove some truncation code -ALTER TABLE exp.PropertyDescriptor ALTER COLUMN StorageColumnName NVARCHAR(255); -ALTER TABLE exp.PropertyDescriptor ALTER COLUMN mvIndicatorStorageColumnName NVARCHAR(275); diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.002-25.003.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.002-25.003.sql deleted file mode 100644 index 1678ce6bbc7..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.002-25.003.sql +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ ---GitHub Issue #652: materialinput Role can be a field name, which has a max length of 200 characters -EXECUTE core.fn_dropifexists 'MaterialInput', 'exp', 'INDEX', 'IDX_MaterialInput_Role'; -ALTER TABLE exp.MaterialInput ALTER COLUMN Role NVARCHAR(200) NOT NULL; -CREATE INDEX IDX_MaterialInput_Role ON exp.MaterialInput(Role); \ No newline at end of file diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.003-25.004.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.003-25.004.sql deleted file mode 100644 index 1d083928e11..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.003-25.004.sql +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ ---Issue 53478: DataInput Role can be a DataClass name, which has a max length of 200 characters -EXECUTE core.fn_dropifexists 'DataInput', 'exp', 'INDEX', 'IDX_DataInput_Role'; -ALTER TABLE exp.DataInput ALTER COLUMN Role NVARCHAR(200) NOT NULL; -CREATE INDEX IDX_DataInput_Role ON exp.DataInput(Role); \ No newline at end of file diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.004-25.005.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.004-25.005.sql deleted file mode 100644 index 5dd15faa9de..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.004-25.005.sql +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- @LongRunningScript('updating all ObjectId columns to BIGINT') - --- Viability no longer supports SQL Server, but its old schema may have been left behind. Ensure it and its FK to ObjectId are dropped. -EXEC core.fn_dropifexists '*', 'viability', 'SCHEMA'; - --- Drop foreign keys that involve ObjectIds -ALTER TABLE exp.Edge DROP CONSTRAINT FK_Edge_From_Object; -ALTER TABLE exp.Edge DROP CONSTRAINT FK_Edge_To_Object; -ALTER TABLE exp.Edge DROP CONSTRAINT FK_Edge_SourceId_Object; -ALTER TABLE exp.ExperimentRun DROP CONSTRAINT FK_ExperimentRun_ObjectId; -ALTER TABLE exp.Material DROP CONSTRAINT FK_Material_ObjectId; -ALTER TABLE exp.Data DROP CONSTRAINT FK_Data_ObjectId; -ALTER TABLE exp.ObjectProperty DROP CONSTRAINT FK_ObjectProperty_Object; -ALTER TABLE exp.Object DROP CONSTRAINT FK_Object_Object; - --- Drop other constraints that involve ObjectIds -ALTER TABLE exp.ObjectProperty DROP CONSTRAINT PK_ObjectProperty; -ALTER TABLE exp.Object DROP CONSTRAINT PK_Object; -ALTER TABLE exp.Edge DROP CONSTRAINT UQ_Edge_FromTo_RunId_SourceId_SourceKey; - --- Drop indexes that involve ObjectIds -DROP INDEX IDX_Object_ContainerOwnerObjectId ON exp.Object; -DROP INDEX IX_Object_OwnerObjectId ON exp.Object; -DROP INDEX IX_Edge_ToObjectId ON exp.Edge; -DROP INDEX IX_Edge_SourceId ON exp.Edge; -DROP INDEX idx_data_objectid ON exp.Data; -DROP INDEX idx_experimentrun_objectid ON exp.ExperimentRun; -DROP INDEX idx_material_objectid ON exp.Material; - --- Change all ObjectId columns to BIGINT. Note: Unlike PostgreSQL, SQL Server does not maintain NOT NULL on INT -> BIGINT type changes. -ALTER TABLE exp.Object ALTER COLUMN ObjectId BIGINT NOT NULL; -ALTER TABLE exp.Object ALTER COLUMN OwnerObjectId BIGINT NULL; -ALTER TABLE exp.ObjectProperty ALTER COLUMN ObjectId BIGINT NOT NULL; -ALTER TABLE exp.Edge ALTER COLUMN FromObjectId BIGINT NOT NULL; -ALTER TABLE exp.Edge ALTER COLUMN ToObjectId BIGINT NOT NULL; -ALTER TABLE exp.Edge ALTER COLUMN SourceId BIGINT NULL; -ALTER TABLE exp.Data ALTER COLUMN ObjectId BIGINT NOT NULL; -ALTER TABLE exp.ExperimentRun ALTER COLUMN ObjectId BIGINT NOT NULL; -ALTER TABLE exp.Material ALTER COLUMN ObjectId BIGINT NOT NULL; -ALTER TABLE exp.ObjectLegacyNames ALTER COLUMN ObjectId BIGINT NOT NULL; - --- Recreate indexes -CREATE UNIQUE INDEX idx_material_objectid ON exp.material (objectid); -CREATE UNIQUE INDEX idx_experimentrun_objectid ON exp.experimentrun (objectid); -CREATE UNIQUE INDEX idx_data_objectid ON exp.data (objectid); -CREATE INDEX IX_Edge_SourceId ON exp.Edge (SourceId); -CREATE INDEX IX_Edge_ToObjectId ON exp.Edge (ToObjectId); -CREATE INDEX IX_Object_OwnerObjectId ON exp.Object (OwnerObjectId) -CREATE CLUSTERED INDEX IDX_Object_ContainerOwnerObjectId ON exp.Object (Container, OwnerObjectId, ObjectId); - --- Recreate constraints -ALTER TABLE exp.Edge ADD CONSTRAINT UQ_Edge_FromTo_RunId_SourceId_SourceKey UNIQUE (FromObjectId, ToObjectId, RunId, SourceId, SourceKey); -ALTER TABLE exp.Object ADD CONSTRAINT PK_Object PRIMARY KEY NONCLUSTERED (ObjectId); -ALTER TABLE exp.ObjectProperty ADD CONSTRAINT PK_ObjectProperty PRIMARY KEY CLUSTERED (ObjectId, PropertyId); - --- Recreate foreign keys -ALTER TABLE exp.Object ADD CONSTRAINT FK_Object_Object FOREIGN KEY (OwnerObjectId) REFERENCES exp.Object (ObjectId); -ALTER TABLE exp.ObjectProperty ADD CONSTRAINT FK_ObjectProperty_Object FOREIGN KEY (ObjectId) REFERENCES exp.Object (ObjectId); -ALTER TABLE exp.Data ADD CONSTRAINT FK_Data_ObjectId FOREIGN KEY (ObjectId) REFERENCES exp.Object (ObjectId); -ALTER TABLE exp.Material ADD CONSTRAINT FK_Material_ObjectId FOREIGN KEY (objectid) REFERENCES exp.object (objectid); -ALTER TABLE exp.ExperimentRun ADD CONSTRAINT FK_ExperimentRun_ObjectId FOREIGN KEY (objectid) REFERENCES exp.object (objectid); -ALTER TABLE exp.Edge ADD CONSTRAINT FK_Edge_SourceId_Object FOREIGN KEY (SourceId) REFERENCES exp.Object (Objectid); -ALTER TABLE exp.Edge ADD CONSTRAINT FK_Edge_To_Object FOREIGN KEY (ToObjectId) REFERENCES exp.object (objectid); -ALTER TABLE exp.Edge ADD CONSTRAINT FK_Edge_From_Object FOREIGN KEY (FromObjectId) REFERENCES exp.object (objectid); - --- Update all stored functions to work with BIGINT ObjectIds (and PropertyIds, just for good measure) - --- This one is not used and not implemented on PostgreSQL, so drop it -DROP PROCEDURE exp.getObjectProperties; - -GO - -CREATE OR ALTER PROCEDURE exp.ensureObject(@container ENTITYID, @lsid LSIDType, @ownerObjectId BIGINT) AS -BEGIN - DECLARE @objectid AS BIGINT - SET NOCOUNT ON - BEGIN TRANSACTION - SELECT @objectid = ObjectId FROM exp.Object WHERE Container=@container AND ObjectURI=@lsid - IF (@objectid IS NULL) - BEGIN - INSERT INTO exp.Object (Container, ObjectURI, OwnerObjectId) VALUES (@container, @lsid, @ownerObjectId) - SELECT @objectid = @@identity - END - COMMIT - SELECT @objectid -END - -GO -CREATE OR ALTER PROCEDURE exp.deleteObject(@container ENTITYID, @lsid LSIDType) AS -BEGIN - SET NOCOUNT ON - DECLARE @objectid BIGINT - SELECT @objectid = ObjectId FROM exp.Object WHERE Container=@container AND ObjectURI=@lsid - IF (@objectid IS NULL) - RETURN - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE ObjectId IN - (SELECT ObjectId FROM exp.Object WHERE OwnerObjectId = @objectid) - DELETE exp.ObjectProperty WHERE ObjectId = @objectid - DELETE exp.Object WHERE OwnerObjectId = @objectid - DELETE exp.Object WHERE ObjectId = @objectid - COMMIT -END - -GO --- internal methods -CREATE OR ALTER PROCEDURE exp._insertFloatProperty(@objectid BIGINT, @propid BIGINT, @float FLOAT) AS -BEGIN - IF (@propid IS NULL OR @objectid IS NULL) RETURN - INSERT INTO exp.ObjectProperty (ObjectId, PropertyId, TypeTag, FloatValue) - VALUES (@objectid, @propid, 'f', @float) -END - -GO -CREATE OR ALTER PROCEDURE exp._insertDateTimeProperty(@objectid BIGINT, @propid BIGINT, @datetime DATETIME) AS -BEGIN - IF (@propid IS NULL OR @objectid IS NULL) RETURN - INSERT INTO exp.ObjectProperty (ObjectId, PropertyId, TypeTag, DateTimeValue) - VALUES (@objectid, @propid, 'd', @datetime) -END - -GO -CREATE OR ALTER PROCEDURE exp._insertStringProperty(@objectid BIGINT, @propid BIGINT, @string VARCHAR(400)) AS -BEGIN - IF (@propid IS NULL OR @objectid IS NULL) RETURN - INSERT INTO exp.ObjectProperty (ObjectId, PropertyId, TypeTag, StringValue) - VALUES (@objectid, @propid, 's', @string) -END - -GO --- --- Set the same property on multiple objects (e.g. impoirt a column of datea) --- --- fast method for importing ObjectProperties (need to wrap with datalayer code) --- - -CREATE OR ALTER PROCEDURE exp.setFloatProperties( - @propertyid BIGINT, - @objectid1 BIGINT, @float1 FLOAT, - @objectid2 BIGINT, @float2 FLOAT, - @objectid3 BIGINT, @float3 FLOAT, - @objectid4 BIGINT, @float4 FLOAT, - @objectid5 BIGINT, @float5 FLOAT, - @objectid6 BIGINT, @float6 FLOAT, - @objectid7 BIGINT, @float7 FLOAT, - @objectid8 BIGINT, @float8 FLOAT, - @objectid9 BIGINT, @float9 FLOAT, - @objectid10 BIGINT, @float10 FLOAT -) AS -BEGIN - SET NOCOUNT ON - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE PropertyId=@propertyid AND ObjectId IN (@objectid1, @objectid2, @objectid3, @objectid4, @objectid5, @objectid6, @objectid7, @objectid8, @objectid9, @objectid10) - EXEC exp._insertFloatProperty @objectid1, @propertyid, @float1 - EXEC exp._insertFloatProperty @objectid2, @propertyid, @float2 - EXEC exp._insertFloatProperty @objectid3, @propertyid, @float3 - EXEC exp._insertFloatProperty @objectid4, @propertyid, @float4 - EXEC exp._insertFloatProperty @objectid5, @propertyid, @float5 - EXEC exp._insertFloatProperty @objectid6, @propertyid, @float6 - EXEC exp._insertFloatProperty @objectid7, @propertyid, @float7 - EXEC exp._insertFloatProperty @objectid8, @propertyid, @float8 - EXEC exp._insertFloatProperty @objectid9, @propertyid, @float9 - EXEC exp._insertFloatProperty @objectid10, @propertyid, @float10 - COMMIT -END - -GO -CREATE OR ALTER PROCEDURE exp.setStringProperties( - @propertyid BIGINT, - @objectid1 BIGINT, @string1 VARCHAR(400), - @objectid2 BIGINT, @string2 VARCHAR(400), - @objectid3 BIGINT, @string3 VARCHAR(400), - @objectid4 BIGINT, @string4 VARCHAR(400), - @objectid5 BIGINT, @string5 VARCHAR(400), - @objectid6 BIGINT, @string6 VARCHAR(400), - @objectid7 BIGINT, @string7 VARCHAR(400), - @objectid8 BIGINT, @string8 VARCHAR(400), - @objectid9 BIGINT, @string9 VARCHAR(400), - @objectid10 BIGINT, @string10 VARCHAR(400) -) AS -BEGIN - SET NOCOUNT ON - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE PropertyId=@propertyid AND ObjectId IN (@objectid1, @objectid2, @objectid3, @objectid4, @objectid5, @objectid6, @objectid7, @objectid8, @objectid9, @objectid10) - EXEC exp._insertStringProperty @objectid1, @propertyid, @string1 - EXEC exp._insertStringProperty @objectid2, @propertyid, @string2 - EXEC exp._insertStringProperty @objectid3, @propertyid, @string3 - EXEC exp._insertStringProperty @objectid4, @propertyid, @string4 - EXEC exp._insertStringProperty @objectid5, @propertyid, @string5 - EXEC exp._insertStringProperty @objectid6, @propertyid, @string6 - EXEC exp._insertStringProperty @objectid7, @propertyid, @string7 - EXEC exp._insertStringProperty @objectid8, @propertyid, @string8 - EXEC exp._insertStringProperty @objectid9, @propertyid, @string9 - EXEC exp._insertStringProperty @objectid10, @propertyid, @string10 - COMMIT -END - -GO -CREATE OR ALTER PROCEDURE exp.setDateTimeProperties( - @propertyid BIGINT, - @objectid1 BIGINT, @datetime1 DATETIME, - @objectid2 BIGINT, @datetime2 DATETIME, - @objectid3 BIGINT, @datetime3 DATETIME, - @objectid4 BIGINT, @datetime4 DATETIME, - @objectid5 BIGINT, @datetime5 DATETIME, - @objectid6 BIGINT, @datetime6 DATETIME, - @objectid7 BIGINT, @datetime7 DATETIME, - @objectid8 BIGINT, @datetime8 DATETIME, - @objectid9 BIGINT, @datetime9 DATETIME, - @objectid10 BIGINT, @datetime10 DATETIME -) AS -BEGIN - SET NOCOUNT ON - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE PropertyId=@propertyid AND ObjectId IN (@objectid1, @objectid2, @objectid3, @objectid4, @objectid5, @objectid6, @objectid7, @objectid8, @objectid9, @objectid10) - EXEC exp._insertDateTimeProperty @objectid1, @propertyid, @datetime1 - EXEC exp._insertDateTimeProperty @objectid2, @propertyid, @datetime2 - EXEC exp._insertDateTimeProperty @objectid3, @propertyid, @datetime3 - EXEC exp._insertDateTimeProperty @objectid4, @propertyid, @datetime4 - EXEC exp._insertDateTimeProperty @objectid5, @propertyid, @datetime5 - EXEC exp._insertDateTimeProperty @objectid6, @propertyid, @datetime6 - EXEC exp._insertDateTimeProperty @objectid7, @propertyid, @datetime7 - EXEC exp._insertDateTimeProperty @objectid8, @propertyid, @datetime8 - EXEC exp._insertDateTimeProperty @objectid9, @propertyid, @datetime9 - EXEC exp._insertDateTimeProperty @objectid10, @propertyid, @datetime10 - COMMIT -END - -GO -CREATE OR ALTER PROCEDURE exp.deleteObjectById(@container ENTITYID, @objectid BIGINT) AS -BEGIN - SET NOCOUNT ON - SELECT @objectid = ObjectId FROM exp.Object WHERE Container=@container AND ObjectId=@objectid - IF (@objectid IS NULL) - RETURN - BEGIN TRANSACTION - DELETE exp.ObjectProperty WHERE ObjectId IN - (SELECT ObjectId FROM exp.Object WHERE OwnerObjectId = @objectid) - DELETE exp.ObjectProperty WHERE ObjectId = @objectid - DELETE exp.Object WHERE OwnerObjectId = @objectid - DELETE exp.Object WHERE ObjectId = @objectid - COMMIT -END - -GO diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.005-25.006.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.005-25.006.sql deleted file mode 100644 index acbe95a1423..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.005-25.006.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- Issue 53561 - store table names at least as long as the maximum identifier length on supported primary databases -ALTER TABLE exp.DomainDescriptor ALTER COLUMN StorageTableName NVARCHAR(150); diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.006-25.007.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.006-25.007.sql deleted file mode 100644 index d09ac89b395..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.006-25.007.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.executeJavaInitializationCode 'ensureBigObjectIds'; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.007-25.008.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.007-25.008.sql deleted file mode 100644 index 46555e2d121..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.007-25.008.sql +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- Update all "security escalation" domains with a proper namespace prefix -UPDATE exp.domainDescriptor SET DomainURI = REPLACE(DomainURI, '--', '-StudySecurityEscalationDomain-') WHERE StorageSchemaName = 'audit' AND (DomainURI LIKE '%StudySecurityEscalationAuditProvider' OR DomainURI LIKE '%StudySecurityEscalationEvent'); -UPDATE exp.domainDescriptor SET DomainURI = REPLACE(DomainURI, '--', '-EHRSecurityEscalationDomain-') WHERE StorageSchemaName = 'audit' AND DomainURI LIKE '%EHRSecurityEscalationEvent'; - --- Update LDAP sync domain with a unique namespace prefix so it doesn't overlap with the ONPRC version -UPDATE exp.domainDescriptor SET DomainURI = REPLACE(DomainURI, 'LdapSyncAuditDomain', 'PremiumLdapSyncAuditDomain') WHERE StorageSchemaName = 'audit' AND DomainURI LIKE '%PremiumLdapAuditEvent'; - --- Update query audit events that advertised the same generic namespace prefix -UPDATE exp.domainDescriptor SET DomainURI = REPLACE(DomainURI, 'QueryAuditDomain', 'QueryExportAuditDomain') WHERE StorageSchemaName = 'audit' AND DomainURI LIKE '%QueryExportAuditEvent'; -UPDATE exp.domainDescriptor SET DomainURI = REPLACE(DomainURI, 'QueryAuditDomain', 'LoggedQueryAuditDomain') WHERE StorageSchemaName = 'audit' AND DomainURI LIKE '%LoggedQuery'; \ No newline at end of file diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.008-25.009.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.008-25.009.sql deleted file mode 100644 index fd6043dffe7..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.008-25.009.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -ALTER TABLE exp.list ALTER COLUMN keyname NVARCHAR(200) NOT NULL; \ No newline at end of file diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.009-25.010.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.009-25.010.sql deleted file mode 100644 index 68fa01cfbb9..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.009-25.010.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.executeJavaInitializationCode 'upgradeAmountsAndUnits'; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.010-25.011.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.010-25.011.sql deleted file mode 100644 index 6d7a943c5fc..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.010-25.011.sql +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- This index overlaps with uq_conditionalformat_propertyid_sortorder -DROP INDEX idx_conditionalformat_propertyid ON exp.ConditionalFormat; --- This index overlaps with uq_alias_name -DROP INDEX ix_alias_name ON exp.Alias; --- This index overlaps with uq_dataclass_container_name -DROP INDEX ix_dataclass_container ON exp.DataClass; --- This index overlaps with uq_protocolappparam_ord -DROP INDEX ix_protocolapplicationparameter_appid ON exp.ProtocolApplicationParameter; --- This index overlaps with uq_protocolparameter_ord -DROP INDEX ix_protocolparameter_protocolid ON exp.ProtocolParameter; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.011-25.012.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.011-25.012.sql deleted file mode 100644 index fd5a512355a..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.011-25.012.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- These tables have FKs to exp.Data without corresponding indices. Add indices to speed up exp.Data delete. -CREATE INDEX IX_DataInput_DataId ON exp.DataInput (DataId); -CREATE INDEX IX_DataAncestors_RowId ON exp.DataAncestors (RowId); diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.012-25.013.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.012-25.013.sql deleted file mode 100644 index 9bbb6a14312..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.012-25.013.sql +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- Not needed since it's redundant with exp.DataInput's PK -DROP INDEX IX_DataInput_DataId ON exp.DataInput; - -CREATE INDEX IX_MaterialAncestors_RowId ON exp.MaterialAncestors (RowId); diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.013-25.014.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.013-25.014.sql deleted file mode 100644 index 802fdbe1de2..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.013-25.014.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -ALTER TABLE exp.ExperimentRun DROP CONSTRAINT FK_Run_WorfklowTask; \ No newline at end of file diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.014-25.015.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.014-25.015.sql deleted file mode 100644 index 6291e7aaac8..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.014-25.015.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.executeJavaUpgradeCode 'dropProvisionedSampleTypeLsidColumn'; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.015-25.016.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-25.015-25.016.sql deleted file mode 100644 index ec291dd4c05..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-25.015-25.016.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.fn_dropifexists 'List', 'exp', 'DEFAULT', 'DiscussionSetting'; -ALTER TABLE exp.List DROP COLUMN DiscussionSetting; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.000-26.001.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-26.000-26.001.sql deleted file mode 100644 index e7c37e6893c..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.000-26.001.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -ALTER TABLE exp.PropertyDescriptor ADD URLTarget NVARCHAR(10) NULL; \ No newline at end of file diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.001-26.002.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-26.001-26.002.sql deleted file mode 100644 index 09b1a730c29..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.001-26.002.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.executeJavaUpgradeCode 'fixContainerForMovedSampleFiles'; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.002-26.003.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-26.002-26.003.sql deleted file mode 100644 index 8d82a916412..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.002-26.003.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.executeJavaUpgradeCode 'addRowIdToProvisionedDataClassTables'; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.003-26.004.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-26.003-26.004.sql deleted file mode 100644 index 4740485a7c0..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.003-26.004.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -UPDATE exp.propertyDescriptor SET concepturi = NULL WHERE concepturi = 'http://www.labkey.org/exp/xml#flag'; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.004-26.005.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-26.004-26.005.sql deleted file mode 100644 index bec43c1bfdc..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.004-26.005.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- SQL Server only -EXEC core.executeJavaUpgradeCode 'shortenAllStorageNames'; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.005-26.006.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-26.005-26.006.sql deleted file mode 100644 index 2af0ee10a00..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.005-26.006.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -EXEC core.executeJavaUpgradeCode 'dropProvisionedDataClassLsidColumn'; diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.006-26.007.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-26.006-26.007.sql deleted file mode 100644 index 796a05c2ea7..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-26.006-26.007.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- For samples, incremental materialized-view updates filter exp.material by (CpasType, Modified) to find rows changed --- since modification began. This index allows for the query to avoid a full table scan. -CREATE INDEX IX_Material_CpasType_Modified ON exp.Material (CpasType, Modified); diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-create.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-create.sql deleted file mode 100644 index 31077509ed0..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-create.sql +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -CREATE VIEW exp.ProtocolActionStepDetailsView AS - SELECT Protocol_P.LSID AS ParentProtocolLSID, Protocol_C.LSID AS LSID, Protocol_C.LSID AS ChildProtocolLSID, exp.ProtocolAction.Sequence AS Sequence, exp.ProtocolAction.Sequence AS ActionSequence, - exp.ProtocolAction.RowId AS ActionId, Protocol_C.RowId AS RowId, Protocol_C.Name AS Name, - Protocol_C.ProtocolDescription AS ProtocolDescription, Protocol_C.ApplicationType AS ApplicationType, - Protocol_C.MaxInputMaterialPerInstance AS MaxInputMaterialPerInstance, Protocol_C.MaxInputDataPerInstance AS MaxInputDataPerInstance, - Protocol_C.OutputMaterialPerInstance AS OutputMaterialPerInstance, Protocol_C.OutputDataPerInstance AS OutputDataPerInstance, Protocol_C.OutputMaterialType AS OutputMaterialType, Protocol_C.OutputDataType AS OutputDataType, - Protocol_C.Instrument AS Instrument, Protocol_C.Software AS Software, Protocol_C.contactId AS contactId, - Protocol_C.Created AS Created, Protocol_C.EntityId AS EntityId, Protocol_C.CreatedBy AS CreatedBy, Protocol_C.Modified AS Modified, Protocol_C.ModifiedBy AS ModifiedBy, Protocol_C.Container AS Container - FROM exp.Protocol Protocol_C INNER JOIN - exp.ProtocolAction ON Protocol_C.RowId = exp.ProtocolAction.ChildProtocolId INNER JOIN - exp.Protocol Protocol_P ON exp.ProtocolAction.ParentProtocolId = Protocol_P.RowId -GO - -CREATE VIEW exp.ProtocolActionPredecessorLSIDView AS - SELECT Action.ParentProtocolLSID, Action.ChildProtocolLSID, Action.ActionSequence, PredecessorAction.ParentProtocolLSID AS PredecessorParentLSID, - PredecessorAction.ChildProtocolLSID AS PredecessorChildLSID, PredecessorAction.ActionSequence AS PredecessorSequence - FROM exp.ProtocolActionPredecessor INNER JOIN - exp.ProtocolActionStepDetailsView PredecessorAction ON exp.ProtocolActionPredecessor.PredecessorId = PredecessorAction.ActionId INNER JOIN - exp.ProtocolActionStepDetailsView Action ON exp.ProtocolActionPredecessor.ActionId = Action.ActionId -GO - -CREATE VIEW exp.PredecessorOutputMaterialsView AS - SELECT exp.ProtocolActionPredecessorLSIDView.ParentProtocolLSID AS RunProtocolLSID, - exp.ProtocolActionPredecessorLSIDView.ChildProtocolLSID AS RunStepProtocolLSID, - exp.ProtocolActionPredecessorLSIDView.ActionSequence AS RunStepSequence, exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID, - exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID, exp.ProtocolActionPredecessorLSIDView.PredecessorSequence, - exp.Material.RowId AS OutputRowId, exp.Material.LSID AS OutputLSID, exp.Material.Name AS OutputName, exp.Material.CpasType AS OutputCpasType, - exp.ExperimentRun.RowId AS RunId - FROM exp.ProtocolApplication INNER JOIN - exp.ExperimentRun ON exp.ProtocolApplication.RunId = exp.ExperimentRun.RowId INNER JOIN - exp.ProtocolActionPredecessorLSIDView ON - exp.ProtocolApplication.ProtocolLSID = exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID AND - exp.ProtocolApplication.ActionSequence = exp.ProtocolActionPredecessorLSIDView.PredecessorSequence AND - exp.ExperimentRun.ProtocolLSID = exp.ProtocolActionPredecessorLSIDView.ParentProtocolLSID INNER JOIN - exp.Material ON exp.ProtocolApplication.RowId = exp.Material.SourceApplicationId - WHERE (exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID <> exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID) -GO - -CREATE VIEW exp.PredecessorRunStartMaterialsView AS -SELECT exp.ProtocolActionPredecessorLSIDView.ParentProtocolLSID AS RunProtocolLSID, - exp.ProtocolActionPredecessorLSIDView.ChildProtocolLSID AS RunStepProtocolLSID, - exp.ProtocolActionPredecessorLSIDView.ActionSequence AS RunStepSequence, exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID, - exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID, exp.ProtocolActionPredecessorLSIDView.PredecessorSequence, - exp.Material.RowId AS OutputRowId, exp.Material.LSID AS OutputLSID, exp.Material.Name AS OutputName, exp.Material.CpasType AS OutputCpasType, - exp.ExperimentRun.RowId AS RunId -FROM exp.ProtocolApplication INNER JOIN - exp.ExperimentRun ON exp.ProtocolApplication.RunId = exp.ExperimentRun.RowId INNER JOIN - exp.ProtocolActionPredecessorLSIDView ON - exp.ProtocolApplication.ProtocolLSID = exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID AND - exp.ProtocolApplication.ActionSequence = exp.ProtocolActionPredecessorLSIDView.PredecessorSequence AND - exp.ExperimentRun.ProtocolLSID = exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID INNER JOIN - exp.MaterialInput ON exp.ProtocolApplication.RowId = exp.MaterialInput.TargetApplicationId INNER JOIN - exp.Material ON exp.MaterialInput.MaterialId = exp.Material.RowId -WHERE (exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID = exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID) -GO - -CREATE VIEW exp.PredecessorAllMaterialsView AS - SELECT * - FROM exp.PredecessorRunStartMaterialsView - UNION - SELECT * - FROM exp.PredecessorOutputMaterialsView -GO - -CREATE VIEW exp.PredecessorOutputDataView AS -SELECT exp.ProtocolActionPredecessorLSIDView.ParentProtocolLSID AS RunProtocolLSID, - exp.ProtocolActionPredecessorLSIDView.ChildProtocolLSID AS RunStepProtocolLSID, - exp.ProtocolActionPredecessorLSIDView.ActionSequence AS RunStepSequence, exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID, - exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID, exp.ProtocolActionPredecessorLSIDView.PredecessorSequence, - exp.Data.RowId AS OutputRowId, exp.Data.LSID AS OutputLSID, exp.Data.Name AS OutputName, exp.Data.CpasType AS OutputCpasType, - exp.ExperimentRun.RowId AS RunId -FROM exp.ProtocolApplication INNER JOIN - exp.ExperimentRun ON exp.ProtocolApplication.RunId = exp.ExperimentRun.RowId INNER JOIN - exp.ProtocolActionPredecessorLSIDView ON - exp.ProtocolApplication.ProtocolLSID = exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID AND - exp.ProtocolApplication.ActionSequence = exp.ProtocolActionPredecessorLSIDView.PredecessorSequence AND - exp.ExperimentRun.ProtocolLSID = exp.ProtocolActionPredecessorLSIDView.ParentProtocolLSID INNER JOIN - exp.Data ON exp.ProtocolApplication.RowId = exp.Data.SourceApplicationId -WHERE (exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID <> exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID) -GO - -CREATE VIEW exp.PredecessorRunStartDataView AS - SELECT exp.ProtocolActionPredecessorLSIDView.ParentProtocolLSID AS RunProtocolLSID, - exp.ProtocolActionPredecessorLSIDView.ChildProtocolLSID AS RunStepProtocolLSID, - exp.ProtocolActionPredecessorLSIDView.ActionSequence AS RunStepSequence, exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID, - exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID, exp.ProtocolActionPredecessorLSIDView.PredecessorSequence, - exp.Data.RowId AS OutputRowId, exp.Data.LSID AS OutputLSID, exp.Data.Name AS OutputName, exp.Data.CpasType AS OutputCpasType, - exp.ExperimentRun.RowId AS RunId - FROM exp.DataInput INNER JOIN - exp.ProtocolApplication INNER JOIN - exp.ExperimentRun ON exp.ProtocolApplication.RunId = exp.ExperimentRun.RowId INNER JOIN - exp.ProtocolActionPredecessorLSIDView ON - exp.ProtocolApplication.ProtocolLSID = exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID AND - exp.ProtocolApplication.ActionSequence = exp.ProtocolActionPredecessorLSIDView.PredecessorSequence AND - exp.ExperimentRun.ProtocolLSID = exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID ON - exp.DataInput.TargetApplicationId = exp.ProtocolApplication.RowId INNER JOIN - exp.Data ON exp.DataInput.DataId = exp.Data.RowId - WHERE (exp.ProtocolActionPredecessorLSIDView.PredecessorChildLSID = exp.ProtocolActionPredecessorLSIDView.PredecessorParentLSID) -GO - -CREATE VIEW exp.PredecessorAllDataView AS - SELECT * - FROM exp.PredecessorRunStartDataView - UNION - SELECT * - FROM exp.PredecessorOutputDataView -GO - -CREATE VIEW exp.ChildMaterialForApplication AS - -SELECT exp.Material.RowId, exp.Material.LSID, exp.Material.Name, exp.Material.SourceApplicationId, exp.Material.RunId, exp.Material.Created, - exp.ProtocolApplication.RowId AS ApplicationID, exp.ProtocolApplication.LSID AS ApplicationLSID, exp.ProtocolApplication.Name AS ApplicationName, - exp.ProtocolApplication.CpasType AS ApplicationType -FROM exp.Material INNER JOIN - exp.ProtocolApplication ON exp.Material.SourceApplicationId = exp.ProtocolApplication.RowId -WHERE (exp.ProtocolApplication.CpasType <> N'ExperimentRunOutput') - -GO - -CREATE VIEW exp.ChildDataForApplication AS - -SELECT exp.Data.RowId, exp.Data.LSID, exp.Data.Name, exp.Data.SourceApplicationId, exp.Data.DataFileUrl, exp.Data.RunId, exp.Data.Created, - exp.ProtocolApplication.RowId AS ApplicationID, exp.ProtocolApplication.LSID AS ApplicationLSID, exp.ProtocolApplication.Name AS ApplicationName, - exp.ProtocolApplication.CpasType AS ApplicationType -FROM exp.Data INNER JOIN - exp.ProtocolApplication ON exp.Data.SourceApplicationId = exp.ProtocolApplication.RowId -WHERE (exp.ProtocolApplication.CpasType <> N'ExperimentRunOutput') - -GO - -CREATE VIEW exp.MarkedOutputMaterialForRun AS - - SELECT exp.Material.RowId, exp.Material.LSID, exp.Material.Name, exp.Material.SourceApplicationId, exp.Material.RunId, exp.Material.Created, - PAStartNode.RowId AS ApplicationID, PAStartNode.LSID AS ApplicationLSID, PAStartNode.Name AS ApplicationName, - PAStartNode.CpasType AS ApplicationCpasType - FROM exp.Material INNER JOIN - exp.MaterialInput ON exp.Material.RowId = exp.MaterialInput.MaterialId INNER JOIN - exp.ProtocolApplication PAMarkOutputNode ON exp.MaterialInput.TargetApplicationId = PAMarkOutputNode.RowId INNER JOIN - exp.ProtocolApplication PAStartNode ON PAMarkOutputNode.RunId = PAStartNode.RunId - WHERE (PAMarkOutputNode.CpasType = N'ExperimentRunOutput') AND (PAStartNode.CpasType = N'ExperimentRun') - -GO - -CREATE VIEW exp.MarkedOutputDataForRun AS - - SELECT exp.Data.RowId, exp.Data.LSID, exp.Data.Name, exp.Data.SourceApplicationId, exp.Data.DataFileUrl, exp.Data.RunId, exp.Data.Created, - PAStartNode.RowId AS ApplicationID, PAStartNode.LSID AS ApplicationLSID, PAStartNode.Name AS ApplicationName, - PAStartNode.CpasType AS ApplicationCpasType - FROM exp.Data INNER JOIN - exp.DataInput ON exp.Data.RowId = exp.DataInput.DataId INNER JOIN - exp.ProtocolApplication PAMarkOutputNode ON exp.DataInput.TargetApplicationId = PAMarkOutputNode.RowId INNER JOIN - exp.ProtocolApplication PAStartNode ON PAMarkOutputNode.RunId = PAStartNode.RunId - WHERE (PAMarkOutputNode.CpasType = N'ExperimentRunOutput') AND (PAStartNode.CpasType = N'ExperimentRun') -GO - -CREATE VIEW exp.OutputMaterialForNode AS - - SELECT RowId, LSID, Name, SourceApplicationId, RunId, Created, ApplicationID, ApplicationLSID, ApplicationName - FROM exp.ChildMaterialforApplication - UNION ALL - SELECT RowId, LSID, Name, SourceApplicationId, RunId, Created, ApplicationID, ApplicationLSID, ApplicationName - FROM exp.MarkedOutputMaterialForRun -GO - -CREATE VIEW exp.OutputDataForNode AS - - SELECT RowId, LSID, Name, SourceApplicationId, DataFileUrl, RunId, Created, ApplicationID, ApplicationLSID, ApplicationName - FROM exp.ChildDataforApplication - UNION ALL - SELECT RowId, LSID, Name, SourceApplicationId, DataFileUrl, RunId, Created, ApplicationID, ApplicationLSID, ApplicationName - FROM exp.MarkedOutputDataForRun -GO - -CREATE VIEW exp.AllLsid AS - SELECT LSID, 'Protocol' AS Type From exp.Protocol UNION - SELECT LSID, 'ProtocolApplication' AS TYPE From exp.ProtocolApplication UNION - SELECT LSID, 'Experiment' AS TYPE From exp.Experiment UNION - SELECT LSID, 'Material' AS TYPE From exp.Material UNION - SELECT LSID, 'MaterialSource' AS TYPE From exp.MaterialSource UNION - SELECT LSID, 'Data' AS TYPE From exp.Data UNION - SELECT LSID, 'ExperimentRun' AS TYPE From exp.ExperimentRun -GO - -CREATE VIEW exp.ExperimentRunDataOutputs AS - SELECT exp.Data.LSID AS DataLSID, exp.ExperimentRun.LSID AS RunLSID, exp.ExperimentRun.Container AS Container - FROM exp.Data - JOIN exp.ExperimentRun ON exp.Data.RunId=exp.ExperimentRun.RowId - WHERE SourceApplicationId IS NOT NULL -GO - -CREATE VIEW exp.ExperimentRunMaterialInputs AS - SELECT exp.ExperimentRun.LSID AS RunLSID, exp.Material.* - FROM exp.ExperimentRun - JOIN exp.ProtocolApplication PAExp ON exp.ExperimentRun.RowId=PAExp.RunId - JOIN exp.MaterialInput ON exp.MaterialInput.TargetApplicationId=PAExp.RowId - JOIN exp.Material ON exp.MaterialInput.MaterialId=exp.Material.RowId - WHERE PAExp.CpasType='ExperimentRun' -GO - -CREATE VIEW exp.ExperimentRunDataInputs AS - SELECT exp.ExperimentRun.LSID AS RunLSID, exp.Data.* - FROM exp.ExperimentRun - JOIN exp.ProtocolApplication PAExp ON exp.ExperimentRun.RowId=PAExp.RunId - JOIN exp.DataInput ON exp.DataInput.TargetApplicationId=PAExp.RowId - JOIN exp.Data ON exp.DataInput.DataId=exp.Data.RowId - WHERE PAExp.CpasType='ExperimentRun' -GO - -CREATE VIEW exp.AllLsidContainers AS - SELECT LSID, Container, 'Protocol' AS Type FROM exp.Protocol UNION ALL - SELECT exp.ProtocolApplication.LSID, Container, 'ProtocolApplication' AS Type FROM exp.ProtocolApplication JOIN exp.Protocol ON exp.Protocol.LSID = exp.ProtocolApplication.ProtocolLSID UNION ALL - SELECT LSID, Container, 'Experiment' AS Type FROM exp.Experiment UNION ALL - SELECT LSID, Container, 'Material' AS Type FROM exp.Material UNION ALL - SELECT LSID, Container, 'MaterialSource' AS Type FROM exp.MaterialSource UNION ALL - SELECT LSID, Container, 'Data' AS Type FROM exp.Data UNION ALL - SELECT LSID, Container, 'ExperimentRun' AS Type FROM exp.ExperimentRun -GO - -CREATE VIEW exp.ObjectClasses AS - SELECT DomainURI - FROM exp.DomainDescriptor -GO - -CREATE VIEW exp.ExperimentRunMaterialOutputs AS - SELECT exp.Material.LSID AS MaterialLSID, exp.ExperimentRun.LSID AS RunLSID, exp.ExperimentRun.Container AS Container - FROM exp.Material - JOIN exp.ExperimentRun ON exp.Material.RunId=exp.ExperimentRun.RowId - WHERE SourceApplicationId IS NOT NULL -GO - -CREATE VIEW exp.ObjectPropertiesView AS - SELECT - O.ObjectId, O.Container, O.ObjectURI, O.OwnerObjectId, - PD.name, PD.PropertyURI, PD.RangeURI, - P.TypeTag, P.FloatValue, P.StringValue, P.DatetimeValue, P.MvIndicator, PD.PropertyId, PD.ConceptURI, PD.Format - FROM exp.ObjectProperty P JOIN exp.Object O ON P.ObjectId = O.ObjectId - JOIN exp.PropertyDescriptor PD ON P.PropertyId = PD.PropertyId -GO diff --git a/experiment/resources/schemas/dbscripts/sqlserver/exp-drop.sql b/experiment/resources/schemas/dbscripts/sqlserver/exp-drop.sql deleted file mode 100644 index 9b5da533497..00000000000 --- a/experiment/resources/schemas/dbscripts/sqlserver/exp-drop.sql +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - --- DROP all views (current and obsolete) - --- NOTE: Don't remove any of these drop statements, even if we stop re-creating the view in *-create.sql. Drop statements must --- remain in place so we can correctly upgrade from older versions, which we commit to for two years after each release. - -EXEC core.fn_dropifexists 'ObjectPropertiesView', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ExperimentRunMaterialOutputs', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ObjectClasses', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'AllLsidContainers', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ExperimentRunDataInputs', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ExperimentRunMaterialInputs', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ExperimentRunDataOutputs', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'AllLsid', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'OutputDataForNode', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'OutputMaterialForNode', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'MarkedOutputDataForRun', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'MarkedOutputMaterialForRun', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ChildDataForApplication', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ChildMaterialForApplication', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'PredecessorAllDataView', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'PredecessorRunStartDataView', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'PredecessorOutputDataView', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'PredecessorAllMaterialsView', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'PredecessorRunStartMaterialsView', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'PredecessorOutputMaterialsView', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ProtocolActionPredecessorLSIDView', 'exp', 'VIEW', NULL -EXEC core.fn_dropifexists 'ProtocolActionStepDetailsView', 'exp', 'VIEW', NULL -GO diff --git a/experiment/src/org/labkey/experiment/ExperimentModule.java b/experiment/src/org/labkey/experiment/ExperimentModule.java index 4b1aca4a025..efcf794a369 100644 --- a/experiment/src/org/labkey/experiment/ExperimentModule.java +++ b/experiment/src/org/labkey/experiment/ExperimentModule.java @@ -31,7 +31,6 @@ 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.DbSchemaType; import org.labkey.api.data.JdbcType; @@ -65,8 +64,8 @@ import org.labkey.api.exp.api.SampleTypeService; import org.labkey.api.exp.api.StorageProvisioner; import org.labkey.api.exp.property.DomainAuditProvider; -import org.labkey.api.exp.property.DomainUtil; import org.labkey.api.exp.property.DomainPropertyAuditProvider; +import org.labkey.api.exp.property.DomainUtil; import org.labkey.api.exp.property.ExperimentProperty; import org.labkey.api.exp.property.PropertyService; import org.labkey.api.exp.property.SystemProperty; @@ -127,8 +126,8 @@ import org.labkey.experiment.api.ExpDataClassType; import org.labkey.experiment.api.ExpDataImpl; import org.labkey.experiment.api.ExpDataTableImpl; -import org.labkey.experiment.api.ExpMaterialTableImpl; import org.labkey.experiment.api.ExpMaterialImpl; +import org.labkey.experiment.api.ExpMaterialTableImpl; import org.labkey.experiment.api.ExpProtocolImpl; import org.labkey.experiment.api.ExpSampleTypeImpl; import org.labkey.experiment.api.ExpSampleTypeTableImpl; @@ -280,19 +279,11 @@ protected void init() OptionalFeatureService.FeatureType.Deprecated)); OptionalFeatureService.get().addExperimentalFeatureFlag(AppProps.EXPERIMENTAL_RESOLVE_PROPERTY_URI_COLUMNS, "Resolve property URIs as columns on experiment tables", "If a column is not found on an experiment table, attempt to resolve the column name as a Property URI and add it as a property column", false, true); - if (CoreSchema.getInstance().getSqlDialect().isSqlServer()) - { - OptionalFeatureService.get().addExperimentalFeatureFlag(NameGenerator.EXPERIMENTAL_WITH_COUNTER, "Use strict incremental withCounter and rootSampleCount expression", - "When withCounter or rootSampleCount is used in name expression, make sure the count increments one-by-one and does not jump.", true); - } - else - { - OptionalFeatureService.get().addExperimentalFeatureFlag(SAMPLE_FILES_TABLE, "Manage Unreferenced Sample Files", - "Enable 'Unreferenced Sample Files' table to view and delete sample files that are no longer referenced by samples", false); + OptionalFeatureService.get().addExperimentalFeatureFlag(SAMPLE_FILES_TABLE, "Manage Unreferenced Sample Files", + "Enable 'Unreferenced Sample Files' table to view and delete sample files that are no longer referenced by samples", false); - OptionalFeatureService.get().addExperimentalFeatureFlag(NameGenerator.EXPERIMENTAL_ALLOW_GAP_COUNTER, "Allow gap with withCounter and rootSampleCount expression", - "Check this option if gaps in the count generated by withCounter or rootSampleCount name expression are allowed.", true); - } + OptionalFeatureService.get().addExperimentalFeatureFlag(NameGenerator.EXPERIMENTAL_ALLOW_GAP_COUNTER, "Allow gap with withCounter and rootSampleCount expression", + "Check this option if gaps in the count generated by withCounter or rootSampleCount name expression are allowed.", true); OptionalFeatureService.get().addExperimentalFeatureFlag(AppProps.QUANTITY_COLUMN_SUFFIX_TESTING, "Quantity column suffix testing", "If a column name contains a \"__\" suffix, this feature allows for testing it as a Quantity display column", false); OptionalFeatureService.get().addExperimentalFeatureFlag(ExperimentService.EXPERIMENTAL_FEATURE_FROM_EXPANCESTORS, "SQL syntax: 'FROM EXPANCESTORS()'", @@ -767,19 +758,17 @@ SELECT COUNT(DISTINCT DD.DomainURI) FROM results.put("autoLinkedSampleSetCount", new SqlSelector(schema, "SELECT COUNT(*) FROM exp.materialsource WHERE autoLinkTargetContainer IS NOT NULL").getObject(Long.class)); results.put("sampleSetCount", new SqlSelector(schema, "SELECT COUNT(*) FROM exp.materialsource").getObject(Long.class)); - if (schema.getSqlDialect().isPostgreSQL()) // SQLServer does not support regular expression queries - { - Collection> numSampleCounts = new SqlSelector(schema, """ - SELECT totalCount, numberNameCount FROM - (SELECT cpastype, COUNT(*) AS totalCount from exp.material GROUP BY cpastype) t - JOIN - (SELECT cpastype, COUNT(*) AS numberNameCount FROM exp.material m WHERE m.name SIMILAR TO '[0-9.]*' GROUP BY cpastype) ns - ON t.cpastype = ns.cpastype""").getMapCollection(); - results.put("sampleSetWithNumberNamesCount", numSampleCounts.size()); - results.put("sampleSetWithOnlyNumberNamesCount", numSampleCounts.stream().filter( - map -> (Long) map.get("totalCount") > 0 && map.get("totalCount") == map.get("numberNameCount") - ).count()); - } + Collection> numSampleCounts = new SqlSelector(schema, """ + SELECT totalCount, numberNameCount FROM + (SELECT cpastype, COUNT(*) AS totalCount from exp.material GROUP BY cpastype) t + JOIN + (SELECT cpastype, COUNT(*) AS numberNameCount FROM exp.material m WHERE m.name SIMILAR TO '[0-9.]*' GROUP BY cpastype) ns + ON t.cpastype = ns.cpastype""").getMapCollection(); + results.put("sampleSetWithNumberNamesCount", numSampleCounts.size()); + results.put("sampleSetWithOnlyNumberNamesCount", numSampleCounts.stream().filter( + map -> (Long) map.get("totalCount") > 0 && map.get("totalCount") == map.get("numberNameCount") + ).count()); + UserSchema userSchema = AuditLogService.getAuditLogSchema(User.getSearchUser(), ContainerManager.getRoot()); FilteredTable table = (FilteredTable) userSchema.getTable(SampleTimelineAuditEvent.EVENT_TYPE); @@ -863,18 +852,16 @@ HAVING COUNT(*) > 1 results.put("dataClassRowCount", new SqlSelector(schema, "SELECT COUNT(*) FROM exp.data WHERE classid IN (SELECT rowid FROM exp.dataclass)").getObject(Long.class)); results.put("dataWithDataParentsCount", new SqlSelector(schema, "SELECT COUNT(DISTINCT d.sourceApplicationId) FROM exp.data d\n" + "JOIN exp.datainput di ON di.targetapplicationid = d.sourceapplicationid").getObject(Long.class)); - if (schema.getSqlDialect().isPostgreSQL()) - { - Collection> numDataClassObjectsCounts = new SqlSelector(schema, """ - SELECT totalCount, numberNameCount FROM - (SELECT cpastype, COUNT(*) AS totalCount from exp.data GROUP BY cpastype) t - JOIN - (SELECT cpastype, COUNT(*) AS numberNameCount FROM exp.data m WHERE m.name SIMILAR TO '[0-9.]*' GROUP BY cpastype) ns - ON t.cpastype = ns.cpastype""").getMapCollection(); - results.put("dataClassWithNumberNamesCount", numDataClassObjectsCounts.size()); - results.put("dataClassWithOnlyNumberNamesCount", numDataClassObjectsCounts.stream().filter(map -> - (Long) map.get("totalCount") > 0 && map.get("totalCount") == map.get("numberNameCount")).count()); - } + + Collection> numDataClassObjectsCounts = new SqlSelector(schema, """ + SELECT totalCount, numberNameCount FROM + (SELECT cpastype, COUNT(*) AS totalCount from exp.data GROUP BY cpastype) t + JOIN + (SELECT cpastype, COUNT(*) AS numberNameCount FROM exp.data m WHERE m.name SIMILAR TO '[0-9.]*' GROUP BY cpastype) ns + ON t.cpastype = ns.cpastype""").getMapCollection(); + results.put("dataClassWithNumberNamesCount", numDataClassObjectsCounts.size()); + results.put("dataClassWithOnlyNumberNamesCount", numDataClassObjectsCounts.stream().filter(map -> + (Long) map.get("totalCount") > 0 && map.get("totalCount") == map.get("numberNameCount")).count()); results.put("ontologyPrincipalConceptCodeCount", new SqlSelector(schema, "SELECT COUNT(*) FROM exp.propertydescriptor WHERE principalconceptcode IS NOT NULL").getObject(Long.class)); results.put("ontologyLookupColumnCount", new SqlSelector(schema, "SELECT COUNT(*) FROM exp.propertydescriptor WHERE concepturi = ?", OntologyService.conceptCodeConceptURI).getObject(Long.class)); diff --git a/experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java b/experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java index 8cde22ec172..216f07e4440 100644 --- a/experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java +++ b/experiment/src/org/labkey/experiment/ExperimentUpgradeCode.java @@ -37,7 +37,6 @@ import org.labkey.api.data.DbScope; import org.labkey.api.data.DbScope.Transaction; import org.labkey.api.data.DeferredUpgrade; -import org.labkey.api.data.ForeignKey; import org.labkey.api.data.JdbcType; import org.labkey.api.data.Parameter; import org.labkey.api.data.ParameterMapStatement; @@ -129,25 +128,13 @@ public static void ensureBigObjectIds(ModuleContext context) DbScope primary = DbScope.getLabKeyScope(); String schemaName = "exp"; long desiredValue = Integer.MAX_VALUE + 1L; - if (primary.getSqlDialect().isPostgreSQL()) - { - String sequenceName = "object_objectid_seq"; - ensureBigObjectIds( - // Calling currval() is not an option since it requires a previous call to nextval() in this database session - new SqlSelector(primary, new SQLFragment("SELECT last_value FROM pg_sequences WHERE schemaname = ? AND sequencename = ?", schemaName, sequenceName)), - newValue -> new SqlExecutor(primary).execute("SELECT setval(?, ?)", schemaName + "." + sequenceName, newValue), - desiredValue - ); - } - else - { - String tableName = schemaName + "." + "Object"; - ensureBigObjectIds( - new SqlSelector(primary, new SQLFragment("SELECT IDENT_CURRENT(?)", tableName)), - newValue -> new SqlExecutor(primary).execute("DBCC CHECKIDENT(?, RESEED, ?)", tableName, newValue), - desiredValue - ); - } + String sequenceName = "object_objectid_seq"; + ensureBigObjectIds( + // Calling currval() is not an option since it requires a previous call to nextval() in this database session + new SqlSelector(primary, new SQLFragment("SELECT last_value FROM pg_sequences WHERE schemaname = ? AND sequencename = ?", schemaName, sequenceName)), + newValue -> new SqlExecutor(primary).execute("SELECT setval(?, ?)", schemaName + "." + sequenceName, newValue), + desiredValue + ); } } @@ -638,11 +625,7 @@ private static void upgradeProvisionedDataClassTable(ExpDataClassImpl dc) // Set NOT NULL constraint SqlExecutor executor = new SqlExecutor(scope); - boolean isPostgreSQL = scope.getSqlDialect().isPostgreSQL(); - if (isPostgreSQL) - executor.execute(new SQLFragment("ALTER TABLE expdataclass.").append(domain.getStorageTableName()).append(" ALTER COLUMN rowId SET NOT NULL")); - else - executor.execute(new SQLFragment("ALTER TABLE expdataclass.").append(domain.getStorageTableName()).append(" ALTER COLUMN rowId INT NOT NULL")); + executor.execute(new SQLFragment("ALTER TABLE expdataclass.").append(domain.getStorageTableName()).append(" ALTER COLUMN rowId SET NOT NULL")); // Add indexes back via StorageProvisioner storageProvisioner.ensureTableIndices(domain); @@ -908,25 +891,7 @@ private static boolean dropDataClassLsid(ExpDataClassImpl dc) else LOG.info("No indices found on table '{}' that contain the lsid column.", provisionedTable.getName()); - DbScope primary = DbScope.getLabKeyScope(); - // postgres automatically drops FK associated with column when column is dropped - if (primary.getSqlDialect().isSqlServer()) - { - boolean hasFKDropped = false; - ForeignKey lsidFKCol = lsidColumn.getFk(); - if (lsidFKCol != null) - { - String lsidFKName = lsidFKCol.getFkName(); - if (lsidFKName != null) - { - StorageProvisionerImpl.get().dropTableConstraints(domain, Collections.singleton(lsidFKName)); - hasFKDropped = true; - } - } - - if (!hasFKDropped) // GitHub Issue 1117: this could happen if the dataclass is created by folder import - LOG.info("No FK found on table '{}' that contain the lsid column.", provisionedTable.getName()); - } + // postgres automatically drops the FK associated with a column when the column is dropped // Remanufacture a property descriptor that matches the original LSID property descriptor. var spec = new PropertyStorageSpec(lsidColumnName, JdbcType.VARCHAR, 300).setNullable(false); diff --git a/experiment/src/org/labkey/experiment/LineageMaximumDepthModuleProperty.java b/experiment/src/org/labkey/experiment/LineageMaximumDepthModuleProperty.java index 521b96e1f8d..74b87f2b093 100644 --- a/experiment/src/org/labkey/experiment/LineageMaximumDepthModuleProperty.java +++ b/experiment/src/org/labkey/experiment/LineageMaximumDepthModuleProperty.java @@ -18,7 +18,6 @@ import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.Nullable; import org.labkey.api.data.Container; -import org.labkey.api.data.CoreSchema; import org.labkey.api.exp.api.ExpLineageOptions; import org.labkey.api.exp.api.ExperimentService; import org.labkey.api.module.Module; @@ -62,7 +61,6 @@ public void validate(@Nullable User user, Container c, @Nullable String value) private static int getMaximumDepth() { - // Issue 37332: SQL Server can hit max recursion depth over 100 generations. - return CoreSchema.getInstance().getSqlDialect().isSqlServer() ? 100 : 1_000; + return 1_000; } } diff --git a/experiment/src/org/labkey/experiment/SpecialCharacterMetricsMaintenanceTask.java b/experiment/src/org/labkey/experiment/SpecialCharacterMetricsMaintenanceTask.java index 2689c052116..08af9595693 100644 --- a/experiment/src/org/labkey/experiment/SpecialCharacterMetricsMaintenanceTask.java +++ b/experiment/src/org/labkey/experiment/SpecialCharacterMetricsMaintenanceTask.java @@ -19,7 +19,6 @@ import org.apache.logging.log4j.Logger; import org.junit.After; import org.junit.Assert; -import org.junit.Assume; import org.junit.Before; import org.junit.Test; import org.labkey.api.collections.CaseInsensitiveHashMap; @@ -96,13 +95,6 @@ public void run(Logger log) Map metric = new LinkedHashMap<>(); metric.put("Run time", new Date()); - if (!dialect.isPostgreSQL()) - { - metric.put("skipped", "nonPostgres"); - SpecialCharacterMetricsProvider.getInstance().updateMetrics(Map.of(SpecialCharacterMetricsProvider.METRIC_KEY, metric)); - return; - } - Map> counts = new LinkedHashMap<>(); for (String type : new String[]{TYPE_TEXT_CHOICE, TYPE_MVTC, TYPE_TEXT, TYPE_MULTILINE, TYPE_DATA_NAME, TYPE_OBJECT_STRING_VALUE}) { @@ -313,9 +305,6 @@ public void cleanup() @Test public void testSpecialCharacterMetrics() throws Exception { - DbScope scope = ExperimentService.get().getSchema().getScope(); - Assume.assumeTrue("Special character metrics are PostgreSQL only", scope.getSqlDialect().isPostgreSQL()); - User user = TestContext.get().getUser(); Container c = JunitUtil.getTestContainer(); Logger log = LogManager.getLogger(TestCase.class); diff --git a/experiment/src/org/labkey/experiment/api/ClosureQueryHelper.java b/experiment/src/org/labkey/experiment/api/ClosureQueryHelper.java index 413a100a114..2354b504469 100644 --- a/experiment/src/org/labkey/experiment/api/ClosureQueryHelper.java +++ b/experiment/src/org/labkey/experiment/api/ClosureQueryHelper.java @@ -36,7 +36,6 @@ import org.labkey.api.data.TableInfo; import org.labkey.api.data.TempTableTracker; import org.labkey.api.data.VirtualTable; -import org.labkey.api.data.dialect.SqlDialect; import org.labkey.api.exp.api.ExpDataClass; import org.labkey.api.exp.api.ExpObject; import org.labkey.api.exp.api.ExpSampleType; @@ -130,63 +129,10 @@ SELECT DISTINCT COALESCE(material.RowId, data.RowId) AS RowId, WHERE Depth_ > 0 AND (materialsource.rowid IS NOT NULL OR dataclass.rowid IS NOT NULL) """; - static String mssqlAncestorClosureCTE = String.format(""" - WITH CTE_ AS ( - - SELECT - RowId, - ObjectId as End_, - '/' + CAST(ObjectId AS VARCHAR(MAX)) + '/' as Path_, - 0 as Depth_ - /*FROM*/ - - UNION ALL - - SELECT CTE_.RowId, Edge.FromObjectId as End_, CTE_.Path_ + CAST(Edge.FromObjectId AS VARCHAR) + '/' as Path_, Depth_ + 1 as Depth_ - FROM CTE_ INNER JOIN exp.Edge ON CTE_.End_ = Edge.ToObjectId - WHERE Depth_ < %d AND 0 = CHARINDEX('/' + CAST(Edge.FromObjectId AS VARCHAR) + '/', Path_) - ) - """, (MAX_ANCESTOR_LOOKUP_DEPTH)); - - static String mssqlAncestorClosureSql = """ - SELECT RowId, CAST(CASE WHEN COUNT(*) = 1 THEN MIN(ancestorRowId) ELSE -1 * COUNT(*) END AS INT) AS ancestorRowId, ancestorTypeId - /*INTO*/ - FROM ( - SELECT DISTINCT CTE_.RowId, - COALESCE(material.rowid, data.rowid) as ancestorRowId, - COALESCE('m' + CAST(materialsource.rowid AS VARCHAR), 'd' + CAST(dataclass.rowid AS VARCHAR)) as ancestorTypeId - FROM CTE_ - LEFT OUTER JOIN exp.material ON End_ = material.objectId LEFT OUTER JOIN exp.materialsource ON material.cpasType = materialsource.lsid - LEFT OUTER JOIN exp.data on End_ = data.objectId LEFT OUTER JOIN exp.dataclass ON data.cpasType = dataclass.lsid - WHERE Depth_ > 0 AND (materialsource.rowid IS NOT NULL OR dataclass.rowid IS NOT NULL)) _inner_ - GROUP BY ancestorTypeId, RowId - """; - - static String mssqlDescendantClosureCTE = String.format(""" - DCTE_ AS ( - - SELECT - RowId, - ObjectId as End_, - '/' + CAST(ObjectId AS VARCHAR(MAX)) + '/' as Path_, - 0 as Depth_ - /*FROM*/ - - UNION ALL - - SELECT DCTE_.RowId, Edge.ToObjectId as End_, DCTE_.Path_ + CAST(Edge.ToObjectId AS VARCHAR) + '/' as Path_, Depth_ + 1 as Depth_ - FROM DCTE_ INNER JOIN exp.Edge ON DCTE_.End_ = Edge.FromObjectId - WHERE Depth_ < %d AND 0 = CHARINDEX('/' + CAST(Edge.ToObjectId AS VARCHAR) + '/', Path_) - ) - """, (MAX_ANCESTOR_LOOKUP_DEPTH)); - - public static SQLFragment selectAndInsertSql(SqlDialect d, SQLFragment from, @Nullable SQLFragment into, @Nullable String insert) + public static SQLFragment selectAndInsertSql(SQLFragment from, @Nullable SQLFragment into, @Nullable String insert) { - String cte; - String select; - - cte = d.isPostgreSQL() ? pgAncestorClosureCTE : mssqlAncestorClosureCTE; - select = d.isPostgreSQL() ? pgAncestorClosureSql : mssqlAncestorClosureSql; + String cte = pgAncestorClosureCTE; + String select = pgAncestorClosureSql; String[] cteParts = StringUtils.splitByWholeSeparator(cte,"/*FROM*/"); assert cteParts.length == 2; @@ -205,12 +151,12 @@ public static SQLFragment selectAndInsertSql(SqlDialect d, SQLFragment from, @Nu return sql; } - public static SQLFragment selectIntoTempTableSql(SqlDialect d, SQLFragment from, @Nullable SQLFragment tempTable) + public static SQLFragment selectIntoTempTableSql(SQLFragment from, @Nullable SQLFragment tempTable) { SQLFragment into = new SQLFragment(" INTO temp.${NAME} "); if (null != tempTable) into = new SQLFragment(" INTO temp.").append(tempTable).append(" "); - return selectAndInsertSql(d, from, into, null); + return selectAndInsertSql(from, into, null); } /* @@ -322,7 +268,7 @@ private static void incrementalRecomputeFromTempTable(SQLFragment familyTempTabl tableNameSql.addTempToken(ref); ttt = TempTableTracker.track(tempTableName, ref); SQLFragment from = new SQLFragment("FROM temp.").append(familyTempTable).append(" WHERE ObjectType = ").appendValue(isSampleType ? "m" : "d").append(" "); - SQLFragment selectInto = selectIntoTempTableSql(getScope().getSqlDialect(), from, tableNameSql); + SQLFragment selectInto = selectIntoTempTableSql(from, tableNameSql); selectInto.addTempToken(ref); int count = new SqlExecutor(getScope()).execute(selectInto); logger.debug("Selected {} rows into temp.{} for recompute of {} ancestors.", count, tempTableName, isSampleType ? "sample" : "data"); @@ -330,7 +276,6 @@ private static void incrementalRecomputeFromTempTable(SQLFragment familyTempTabl SQLFragment upsert; TableInfo tInfo = isSampleType ? ExperimentServiceImpl.get().getTinfoMaterialAncestors() : ExperimentServiceImpl.get().getTinfoDataAncestors(); DbScope scope = tInfo.getSchema().getScope(); - SqlDialect dialect = scope.getSqlDialect(); // delete the ancestor data for the ids in the family new SqlExecutor(getScope()).execute(invalidateAncestorData(tInfo, familyTempTable, isSampleType)); @@ -338,23 +283,11 @@ private static void incrementalRecomputeFromTempTable(SQLFragment familyTempTabl if (count == 0) return; - if (dialect.isPostgreSQL()) - { - upsert = new SQLFragment() - .append("INSERT INTO ").append(tInfo) - .append(" (RowId, AncestorRowId, AncestorTypeId)\n") - .append("SELECT RowId, ancestorRowId, ancestorTypeId FROM temp.").append(tableNameSql).append(" TMP\n") - .append("ON CONFLICT(RowId,ancestorTypeId) DO UPDATE SET ancestorRowId = EXCLUDED.ancestorRowId").appendEOS(); - } - else - { - upsert = new SQLFragment() - .append("MERGE ").append(tInfo, "Target") - .append(" USING (SELECT RowId, AncestorRowId, AncestorTypeId FROM temp.").append(tableNameSql) - .append(") AS Source ON Target.RowId=Source.RowId AND Target.AncestorTypeId=Source.ancestorTypeId\n") - .append("WHEN MATCHED THEN UPDATE SET Target.AncestorTypeId = Source.ancestorTypeId\n") - .append("WHEN NOT MATCHED THEN INSERT (RowId, AncestorRowId, AncestorTypeId) VALUES (Source.RowId, Source.ancestorRowId, Source.ancestorTypeId)").appendEOS(); - } + upsert = new SQLFragment() + .append("INSERT INTO ").append(tInfo) + .append(" (RowId, AncestorRowId, AncestorTypeId)\n") + .append("SELECT RowId, ancestorRowId, ancestorTypeId FROM temp.").append(tableNameSql).append(" TMP\n") + .append("ON CONFLICT(RowId,ancestorTypeId) DO UPDATE SET ancestorRowId = EXCLUDED.ancestorRowId").appendEOS(); upsert.addTempToken(ref); new SqlExecutor(scope).execute(upsert); } @@ -399,7 +332,7 @@ public static void populateMaterialAncestors(Logger logger) { logger.debug(" Adding rows from samples in sampleType {}", sampleType.getName()); SQLFragment from = new SQLFragment(" FROM exp.material WHERE materialSourceId = ?").add(sampleType.getRowId()); - SQLFragment sql = ClosureQueryHelper.selectAndInsertSql(schema.getSqlDialect(), from, null, "INSERT INTO exp.materialAncestors (RowId, AncestorRowId, AncestorTypeId) "); + SQLFragment sql = ClosureQueryHelper.selectAndInsertSql(from, null, "INSERT INTO exp.materialAncestors (RowId, AncestorRowId, AncestorTypeId) "); int numRows = new SqlExecutor(schema.getScope()).execute(sql); totalRows += numRows; logger.debug(" Added {} rows for data class {}", numRows, sampleType.getName()); @@ -422,7 +355,7 @@ public static void populateDataAncestors(Logger logger) { logger.debug(" Adding rows to exp.dataAncestors from data class {}", dataClass.getName()); SQLFragment from = new SQLFragment(" FROM exp.data WHERE classId = ?").add(dataClass.getRowId()); - SQLFragment sql = ClosureQueryHelper.selectAndInsertSql(schema.getSqlDialect(), from, null, + SQLFragment sql = ClosureQueryHelper.selectAndInsertSql(from, null, "INSERT INTO exp.dataAncestors (RowId, AncestorRowId, AncestorTypeId) "); int numRows = new SqlExecutor(schema.getScope()).execute(sql); totalRows += numRows; @@ -466,9 +399,6 @@ public static void recomputeFromSeeds(SQLFragment selectSeedsSql, boolean isSamp // add the seed ids to the temp table SQLFragment selectIntoSql = new SQLFragment("SELECT RowId, ObjectId, ObjectType INTO temp.").append(tableNameSql).append(" FROM (").append(selectSeedsSql).append(") x"); - if (getScope().getSqlDialect().isSqlServer()) - // complete hack to get SQLServer to not make RowId an identity column in the target table so the subsequent insert will work without complaint - selectIntoSql.append(" UNION ALL SELECT RowId, ObjectId, 'x' AS ObjectType FROM " ).append(isSampleType ? "exp.material" : "exp.data").append(" WHERE 1 <> 1"); int numSeeds = new SqlExecutor(getScope()).execute(selectIntoSql); logger.debug("Added {} seed {} rows to temp.{}", numSeeds, isSampleType ? "sample" : "data", familyTableName); // if we didn't actually insert any items into the table, there's nothing more to be done @@ -477,7 +407,7 @@ public static void recomputeFromSeeds(SQLFragment selectSeedsSql, boolean isSamp // add the descendants ids to the temp table SQLFragment descendants = new SQLFragment(); - String cte = getScope().getSqlDialect().isPostgreSQL() ? "WITH RECURSIVE " + pgDescendantClosureCTE : "WITH " + mssqlDescendantClosureCTE; + String cte = "WITH RECURSIVE " + pgDescendantClosureCTE; String[] cteParts = StringUtils.splitByWholeSeparator(cte, "/*FROM*/"); SQLFragment descendantsCte = new SQLFragment(); descendantsCte.append(cteParts[0]).append("FROM (SELECT * FROM temp.").append(tableNameSql).append(") s ").append(cteParts[1]); diff --git a/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp b/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp index 52d436bd9de..0d924d22943 100644 --- a/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp +++ b/experiment/src/org/labkey/experiment/api/ExpDataClassDataTestCase.jsp @@ -17,7 +17,10 @@ <%@ page import="org.apache.commons.lang3.StringUtils" %> <%@ page import="org.jetbrains.annotations.NotNull" %> <%@ page import="org.junit.After" %> +<%@ page import="org.junit.AfterClass" %> +<%@ page import="static org.junit.Assert.*" %> <%@ page import="org.junit.Before" %> +<%@ page import="org.junit.BeforeClass" %> <%@ page import="org.junit.Test" %> <%@ page import="org.labkey.api.action.ApiUsageException" %> <%@ page import="org.labkey.api.audit.AuditLogService" %> @@ -41,7 +44,6 @@ <%@ page import="org.labkey.api.dataiterator.DataIteratorContext" %> <%@ page import="org.labkey.api.dataiterator.DetailedAuditLogDataIterator" %> <%@ page import="org.labkey.api.dataiterator.MapDataIterator" %> -<%@ page import="org.labkey.api.exp.ExperimentException" %> <%@ page import="org.labkey.api.exp.ObjectProperty" %> <%@ page import="org.labkey.api.exp.OntologyManager" %> <%@ page import="org.labkey.api.exp.PropertyDescriptor" %> @@ -97,19 +99,16 @@ <%@ page import="java.util.Collections" %> <%@ page import="java.util.HashMap" %> <%@ page import="java.util.HashSet" %> -<%@ page import="static java.util.Collections.emptyList" %> -<%@ page import="static org.junit.Assert.*" %> <%@ page import="java.util.List" %> <%@ page import="java.util.Map" %> <%@ page import="java.util.Set" %> <%@ page import="java.util.concurrent.TimeUnit" %> <%@ page import="java.util.stream.Collectors" %> -<%@ page import="static org.labkey.api.util.PageFlowUtil.encodeURIComponent" %> +<%@ page import="static java.util.Collections.emptyList" %> +<%@ page import="static org.hamcrest.Matchers.containsString" %> <%@ page import="static org.labkey.api.util.IntegerUtils.asInteger" %> <%@ page import="static org.labkey.api.util.IntegerUtils.asLong" %> -<%@ page import="static org.hamcrest.Matchers.containsString" %> -<%@ page import="org.junit.BeforeClass" %> -<%@ page import="org.junit.AfterClass" %> +<%@ page import="static org.labkey.api.util.PageFlowUtil.encodeURIComponent" %> <%@ page extends="org.labkey.api.jsp.JspTest.BVT" %> <%! @@ -379,7 +378,7 @@ private void testDeleteExpDataClass(ExpDataClassImpl dataClass, User user, Table assertNull(ExperimentService.get().getDataClass(c, table.getName())); assertNull(PropertyService.get().getDomain(c, typeURI)); - UserSchema schema1 = QueryService.get().getUserSchema(user, c, helper.expDataSchemaKey); + UserSchema schema1 = QueryService.get().getUserSchema(user, c, ExpProvisionedTableTestHelper.expDataSchemaKey); assertNull(schema1.getTable(table.getName())); dbTable = dbSchema.getTable(storageTableName); @@ -607,7 +606,7 @@ public void testDomainTemplate() throws Exception } // verify the "TodoList" DataClass was created and data was imported - UserSchema expSchema = QueryService.get().getUserSchema(_user, sub, helper.expDataSchemaKey); + UserSchema expSchema = QueryService.get().getUserSchema(_user, sub, ExpProvisionedTableTestHelper.expDataSchemaKey); TableInfo table = expSchema.getTable("TodoList"); assertNotNull("data class not in query schema", table); @@ -710,37 +709,9 @@ public void testContainerDelete() throws Exception } } -// Issue 26129: sqlserver maximum size of index keys must be < 900 bytes -@Test -public void testLargeUniqueOnSingleColumnOnly() throws ExperimentException -{ - List props = new ArrayList<>(); - props.add(new GWTPropertyDescriptor("aa", "int")); - props.add(new GWTPropertyDescriptor("bb", "multiLine")); - - List indices = new ArrayList<>(); - indices.add(new GWTIndex(List.of("aa", "bb"), true)); - - boolean sqlServer = ExperimentService.get().getSchema().getSqlDialect().isSqlServer(); - try - { - final ExpDataClassImpl dataClass = ExperimentServiceImpl.get().createDataClass(c, _user, "largeUnique", null, props, indices, null, null); - if (sqlServer) - fail("Expected exception creating large index over two columns"); - } - catch (IllegalArgumentException ex) - { - // Not supported on SQL Server - String msg = ex.getMessage(); - String expected = "Index over large columns is not supported"; - assertTrue("Unexpected message: " + ex.getMessage(), msg.contains(expected)); - } -} - @Test public void testLargeUnique() throws Exception { - boolean sqlServer = ExperimentService.get().getSchema().getSqlDialect().isSqlServer(); List props = new ArrayList<>(); props.add(new GWTPropertyDescriptor("aa", "int")); GWTPropertyDescriptor prop = new GWTPropertyDescriptor("bb", "multiLine"); @@ -751,18 +722,7 @@ public void testLargeUnique() throws Exception DataClassDomainKindProperties options = new DataClassDomainKindProperties(); options.setNameExpression("JUNIT-${genId}-${aa}"); - ExpDataClassImpl dataClass; - try - { - dataClass = ExperimentServiceImpl.get().createDataClass(c, _user, "largeUnique2", options, props, indices, null, null); - } - catch (IllegalArgumentException e) - { - // Not supported on SQL Server, so create with no indices - assertTrue("Expected exception creating large index over two columns", e.getMessage().contains("Index over large columns is not supported")); - assertTrue(sqlServer); - dataClass = ExperimentServiceImpl.get().createDataClass(c, _user, "largeUnique2", options, props, List.of(), null, null); - } + ExpDataClassImpl dataClass = ExperimentServiceImpl.get().createDataClass(c, _user, "largeUnique2", options, props, indices, null, null); List> rows = new ArrayList<>(); Map row = new CaseInsensitiveHashMap<>(); @@ -788,8 +748,7 @@ public void testLargeUnique() throws Exception try (DbScope.Transaction tx = ExperimentService.get().getSchema().getScope().beginTransaction()) { helper.insertRows(c, rows, dataClass.getName()); - if (!sqlServer) - fail("Expected constraint exception"); + fail("Expected constraint exception"); } catch (BatchValidationException e) { @@ -930,7 +889,7 @@ public void testViewSupportForVocabularyDomains() throws Exception ExpDataClassImpl dataClass = ExperimentServiceImpl.get().createDataClass(c, _user, dataClassName, null, List.of(new GWTPropertyDescriptor("OtherProp", "string")), emptyList(), null, null); - UserSchema userSchema = QueryService.get().getUserSchema(_user, c, helper.expDataSchemaKey); + UserSchema userSchema = QueryService.get().getUserSchema(_user, c, ExpProvisionedTableTestHelper.expDataSchemaKey); // insert a data class with vocab look up prop using row id of inserted sample ArrayListMap rowToInsert = newArrayListMap(); diff --git a/experiment/src/org/labkey/experiment/api/ExpDataClassType.java b/experiment/src/org/labkey/experiment/api/ExpDataClassType.java index 03abdd94eaf..0a56f7e9d23 100644 --- a/experiment/src/org/labkey/experiment/api/ExpDataClassType.java +++ b/experiment/src/org/labkey/experiment/api/ExpDataClassType.java @@ -65,9 +65,9 @@ public static AttachmentParentType get() TableInfo tableInfo = ExperimentService.get().getTinfoDataClass(); SqlDialect dialect = tableInfo.getSqlDialect(); - // Get a dialect-specific expression that can extract an ObjectId from the LSID column and a WHERE clause to - // filter the rows to LSIDs containing ObjectIds - Pair pair = Lsid.getSqlExpressionToExtractObjectId(new SQLFragment("LSID"), tableInfo.getSqlDialect()); + // Get an expression that can extract an ObjectId from the LSID column and a WHERE clause to filter the rows + // to LSIDs containing ObjectIds + Pair pair = Lsid.getSqlExpressionToExtractObjectId(new SQLFragment("LSID")); SQLFragment expressionToExtractObjectId = pair.first; SQLFragment where = pair.second; diff --git a/experiment/src/org/labkey/experiment/api/ExpMaterialTableImpl.java b/experiment/src/org/labkey/experiment/api/ExpMaterialTableImpl.java index 51fac4f4ef3..8ed529f946a 100644 --- a/experiment/src/org/labkey/experiment/api/ExpMaterialTableImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExpMaterialTableImpl.java @@ -1587,9 +1587,7 @@ void executeIncrementalRollup() { var d = CoreSchema.getInstance().getSchema().getSqlDialect(); SQLFragment incremental = new SQLFragment(); - if (d.isPostgreSQL()) - { - incremental + incremental .append("UPDATE temp.${NAME} AS st\n") .append("SET aliquotcount = expm.aliquotcount, availablealiquotcount = expm.availablealiquotcount, aliquotvolume = expm.aliquotvolume, availablealiquotvolume = expm.availablealiquotvolume, aliquotunit = expm.aliquotunit\n") .append("FROM exp.Material AS expm\n") @@ -1600,22 +1598,6 @@ void executeIncrementalRollup() .append(" st.availablealiquotvolume IS DISTINCT FROM expm.availablealiquotvolume OR ") .append(" st.aliquotunit IS DISTINCT FROM expm.aliquotunit") .append(")"); - } - else - { - // SQL Server 2022 supports IS DISTINCT FROM - incremental - .append("UPDATE st\n") - .append("SET aliquotcount = expm.aliquotcount, availablealiquotcount = expm.availablealiquotcount, aliquotvolume = expm.aliquotvolume, availablealiquotvolume = expm.availablealiquotvolume, aliquotunit = expm.aliquotunit\n") - .append("FROM temp.${NAME} st, exp.Material expm\n") - .append("WHERE expm.rowid = st.rowid AND expm.cpastype = ").appendValue(_lsid,d).append(" AND (\n") - .append(" COALESCE(st.aliquotcount,-2147483648) <> COALESCE(expm.aliquotcount,-2147483648) OR ") - .append(" COALESCE(st.availablealiquotcount,-2147483648) <> COALESCE(expm.availablealiquotcount,-2147483648) OR ") - .append(" COALESCE(st.aliquotvolume,-2147483648) <> COALESCE(expm.aliquotvolume,-2147483648) OR ") - .append(" COALESCE(st.availablealiquotvolume,-2147483648) <> COALESCE(expm.availablealiquotvolume,-2147483648) OR ") - .append(" COALESCE(st.aliquotunit,'-') <> COALESCE(expm.aliquotunit,'-')") - .append(")"); - } upsertWithRetry(incremental); } @@ -1640,12 +1622,8 @@ void executeIncrementalUpdate() SQLFragment buildIncrementalUpdateSql(@NotNull Timestamp changedSince) { - SqlDialect d = CoreSchema.getInstance().getSchema().getSqlDialect(); - // SQL Server's datetime type lacks microsecond precision - Timestamp comparison = d.isSqlServer() ? new Timestamp(changedSince.getTime() - 500) : changedSince; - SQLFragment sql = new SQLFragment("WITH wModified AS (\n") - .append("SELECT rowId FROM exp.material expm WHERE expm.modified >= ?\n").add(comparison) + .append("SELECT rowId FROM exp.material expm WHERE expm.modified >= ?\n").add(changedSince) .append(")\n"); SQLFragment src = new SQLFragment() @@ -1653,18 +1631,9 @@ SQLFragment buildIncrementalUpdateSql(@NotNull Timestamp changedSince) .append("UNION\n") .append(getViewSourceSql()).append(" AND m.rootmaterialrowid IN (SELECT rowId FROM wModified)\n"); - if (d.isPostgreSQL()) - { - sql.append("UPDATE temp.${NAME} AS st\nSET "); - appendSetFromSrc(sql); - sql.append("\nFROM (").append(src).append("\n) src\n").append("WHERE st.rowid = src.rowid"); - } - else - { - sql.append("UPDATE st\nSET "); - appendSetFromSrc(sql); - sql.append("\nFROM temp.${NAME} st INNER JOIN (").append(src).append("\n) src ON st.rowid = src.rowid"); - } + sql.append("UPDATE temp.${NAME} AS st\nSET "); + appendSetFromSrc(sql); + sql.append("\nFROM (").append(src).append("\n) src\n").append("WHERE st.rowid = src.rowid"); return sql; } @@ -1833,7 +1802,7 @@ public SampleTypeAmountDisplayColumn(TableInfo parent, String amountFieldName, S .append(" = ? AND ").append(ExprColumn.STR_TABLE_ALIAS + ".").append(amountFieldName) .append(" IS NOT NULL THEN CAST(").append(ExprColumn.STR_TABLE_ALIAS + ".").append(amountFieldName) .append(" / ? AS ") - .append(parent.getSqlDialect().isPostgreSQL() ? "DECIMAL" : "DOUBLE PRECISION") + .append("DECIMAL") .append(") ELSE ").append(ExprColumn.STR_TABLE_ALIAS + ".").append(amountFieldName) .append(" END)") .add(typeUnit.getBase().toString()) diff --git a/experiment/src/org/labkey/experiment/api/ExperimentRunGraph2.jsp b/experiment/src/org/labkey/experiment/api/ExperimentRunGraph2.jsp index ac8fba2d685..fbd67c6567c 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentRunGraph2.jsp +++ b/experiment/src/org/labkey/experiment/api/ExperimentRunGraph2.jsp @@ -16,8 +16,6 @@ */ %> <%@ page import="org.apache.commons.lang3.StringUtils" %> -<%@ page import="org.labkey.api.data.CoreSchema" %> -<%@ page import="org.labkey.api.data.dialect.SqlDialect" %> <%@ page import="org.labkey.api.exp.api.ExpLineageOptions" %> <%@ page import="org.labkey.api.util.HtmlString" %> <%@ page import="org.labkey.api.view.HttpView" %> @@ -27,12 +25,10 @@ -- we could have multiple files, or multiple multi-line string constants, but it's easier to develop this way. <% - SqlDialect dialect = CoreSchema.getInstance().getSqlDialect(); var bean = (ExpLineageOptions) HttpView.currentModel(); String expType = Objects.toString(bean.getExpTypeValue(), "ALL"); - // See Issue 37332, better (but more complicated) fix for sql server would be to use "option (maxrecursion 1000)" int depth = bean.getConfiguredDepth(); - var CONCAT = HtmlString.unsafe(dialect.isPostgreSQL() ? "||" : "+"); + var CONCAT = HtmlString.unsafe("||"); assert ExpLineageOptions.LineageExpType.fromValue(expType) != null; diff --git a/experiment/src/org/labkey/experiment/api/ExperimentRunGraphForLookup2.jsp b/experiment/src/org/labkey/experiment/api/ExperimentRunGraphForLookup2.jsp index d32eed181a3..7fd5ea1c1b9 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentRunGraphForLookup2.jsp +++ b/experiment/src/org/labkey/experiment/api/ExperimentRunGraphForLookup2.jsp @@ -35,9 +35,8 @@ SqlDialect dialect = CoreSchema.getInstance().getSqlDialect(); var bean = (ExpLineageOptions) HttpView.currentModel(); String expType = Objects.toString(bean.getExpTypeValue(), "ALL"); - // See Issue 37332, better (but more complicated) fix for sql server would be to use "option (maxrecursion 1000)" int depth = bean.getConfiguredDepth(); - var CONCAT = unsafe(dialect.isPostgreSQL() ? "||" : "+"); + var CONCAT = unsafe("||"); String varcharType = dialect.getSqlTypeName(JdbcType.VARCHAR); diff --git a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java index 2c69fe0ddfa..7553e64e97e 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java +++ b/experiment/src/org/labkey/experiment/api/ExperimentServiceImpl.java @@ -308,7 +308,6 @@ import static org.labkey.api.data.NameGenerator.ANCESTOR_INPUT_PREFIX_DATA; import static org.labkey.api.data.NameGenerator.ANCESTOR_INPUT_PREFIX_MATERIAL; import static org.labkey.api.data.NameGenerator.EXPERIMENTAL_ALLOW_GAP_COUNTER; -import static org.labkey.api.data.NameGenerator.EXPERIMENTAL_WITH_COUNTER; import static org.labkey.api.dataiterator.DataIteratorUtil.DUPLICATE_COLUMN_IN_DATA_ERROR; import static org.labkey.api.exp.OntologyManager.getTinfoDomainDescriptor; import static org.labkey.api.exp.OntologyManager.getTinfoObject; @@ -2783,20 +2782,18 @@ private Pair getRunGraphCommonTableExpressions(SQLFragment ret, S String edgesToken = null; - boolean recursive = dialect.isPostgreSQL(); - String parentsToken = null; if (options.isParents()) { String parentsInnerSelect = map.get("$PARENTS_INNER$"); SQLFragment parentsInnerSelectFrag = SQLFragment.unsafe(parentsInnerSelect); parentsInnerSelectFrag.addAll(lsidsFrag.getParams()); - String parentsInnerToken = ret.addCommonTableExpression(dialect, parentsInnerSelect, "org_lk_exp_PARENTS_INNER", parentsInnerSelectFrag, recursive); + String parentsInnerToken = ret.addCommonTableExpression(dialect, parentsInnerSelect, "org_lk_exp_PARENTS_INNER", parentsInnerSelectFrag, true); String parentsSelect = map.get("$PARENTS$"); parentsSelect = Strings.CS.replace(parentsSelect, "$PARENTS_INNER$", parentsInnerToken); // don't use parentsSelect as key, it may not consolidate correctly because of parentsInnerToken - parentsToken = ret.addCommonTableExpression(dialect, "$PARENTS$/" + Objects.toString(options.getExpTypeValue(), "ALL") + "/" + parentsInnerSelect, "org_lk_exp_PARENTS", SQLFragment.unsafe(parentsSelect), recursive); + parentsToken = ret.addCommonTableExpression(dialect, "$PARENTS$/" + Objects.toString(options.getExpTypeValue(), "ALL") + "/" + parentsInnerSelect, "org_lk_exp_PARENTS", SQLFragment.unsafe(parentsSelect), true); } String childrenToken = null; @@ -2806,12 +2803,12 @@ private Pair getRunGraphCommonTableExpressions(SQLFragment ret, S childrenInnerSelect = Strings.CS.replace(childrenInnerSelect, "$EDGES$", edgesToken); SQLFragment childrenInnerSelectFrag = SQLFragment.unsafe(childrenInnerSelect); childrenInnerSelectFrag.addAll(lsidsFrag.getParams()); - String childrenInnerToken = ret.addCommonTableExpression(dialect, childrenInnerSelect, "org_lk_exp_CHILDREN_INNER", childrenInnerSelectFrag, recursive); + String childrenInnerToken = ret.addCommonTableExpression(dialect, childrenInnerSelect, "org_lk_exp_CHILDREN_INNER", childrenInnerSelectFrag, true); String childrenSelect = map.get("$CHILDREN$"); childrenSelect = Strings.CS.replace(childrenSelect, "$CHILDREN_INNER$", childrenInnerToken); // don't use childrenSelect as key, it may not consolidate correctly because of childrenInnerToken - childrenToken = ret.addCommonTableExpression(dialect, "$CHILDREN$/" + Objects.toString(options.getExpTypeValue(), "ALL") + "/" + childrenInnerSelect, "org_lk_exp_CHILDREN", SQLFragment.unsafe(childrenSelect), recursive); + childrenToken = ret.addCommonTableExpression(dialect, "$CHILDREN$/" + Objects.toString(options.getExpTypeValue(), "ALL") + "/" + childrenInnerSelect, "org_lk_exp_CHILDREN", SQLFragment.unsafe(childrenSelect), true); } return new Pair<>(parentsToken,childrenToken); @@ -2996,7 +2993,7 @@ else if (options.isForLookup()) private void removeEdgesForRun(long runId) { TableInfo edge = getTinfoEdge(); - int count = new SqlExecutor(edge.getSchema().getScope()).execute("DELETE FROM " + edge /* + (edge.getSqlDialect().isSqlServer() ? " WITH (TABLOCK, HOLDLOCK)" : "") */ + " WHERE runId=?", runId); + int count = new SqlExecutor(edge.getSchema().getScope()).execute("DELETE FROM " + edge + " WHERE runId=?", runId); LOG.debug("Removed edges for run {}; count = {}", runId, count); } @@ -3215,7 +3212,6 @@ private void insertEdges(List> params) { TableInfo edge = getTinfoEdge(); String edgeSql = "INSERT INTO " + edge + - /* (edge.getSqlDialect().isSqlServer() ? " WITH (TABLOCK, HOLDLOCK)" : "") + */ " (fromObjectId, toObjectId, runId)\n"+ "VALUES (?, ?, ?)"; Table.batchExecute(getExpSchema(), edgeSql, params); @@ -7488,7 +7484,7 @@ private void createMaterialInputParams(List protAppRecords, L TableInfo pa = getTinfoProtocolApplication(); SQLFragment sqlfilter = new SimpleFilter(FieldKey.fromParts("LSID"), protAppRowMap.keySet(), IN).getSQLFragment(pa, "pa"); - new SqlSelector(pa.getSchema(), new SQLFragment("SELECT Lsid, RowId FROM " + pa /* + (pa.getSqlDialect().isSqlServer() ? " WITH (UPDLOCK, HOLDLOCK)" : "") */ + " ") + new SqlSelector(pa.getSchema(), new SQLFragment("SELECT Lsid, RowId FROM " + pa + " ") .append(sqlfilter)).forEach(rs -> { if (protAppRowMap.containsKey(rs.getString("Lsid"))) @@ -10384,14 +10380,7 @@ public void handleAssayNameChange(String newAssayName, String oldAssayName, Assa @Override public boolean useStrictCounter() { - if (CoreSchema.getInstance().getSqlDialect().isSqlServer()) - { - return AppProps.getInstance().isOptionalFeatureEnabled(EXPERIMENTAL_WITH_COUNTER); - } - else - { - return !AppProps.getInstance().isOptionalFeatureEnabled(EXPERIMENTAL_ALLOW_GAP_COUNTER); - } + return !AppProps.getInstance().isOptionalFeatureEnabled(EXPERIMENTAL_ALLOW_GAP_COUNTER); } @Override @@ -10899,22 +10888,20 @@ Map getParts(ExpLineageOptions options, String csv) List getParents(long seed) { - SqlDialect d = getExpSchema().getSqlDialect(); var maps = getParts(new _ExpLineageOptions(tableName), String.valueOf(seed)); String parentsInner = maps.get("$PARENTS_INNER$").replace("$SELF$", "parents"); SQLFragment sql = new SQLFragment() - .append(d.isPostgreSQL() ? "WITH RECURSIVE" : "WITH").append(" parents AS (").append(parentsInner).append(")\n") + .append("WITH RECURSIVE").append(" parents AS (").append(parentsInner).append(")\n") .append("SELECT * FROM parents WHERE self != fromObjectId"); return new SqlSelector(getExpSchema(),sql).getArrayList(InnerResult.class); } List getChildren(long seed) { - SqlDialect d = getExpSchema().getSqlDialect(); var maps = getParts(new _ExpLineageOptions(tableName), String.valueOf(seed)); String childrenInner = maps.get("$CHILDREN_INNER$").replace("$SELF$", "children"); SQLFragment sql = new SQLFragment() - .append(d.isPostgreSQL() ? "WITH RECURSIVE" : "WITH").append(" children AS (").append(childrenInner).append(")\n") + .append("WITH RECURSIVE").append(" children AS (").append(childrenInner).append(")\n") .append("SELECT * FROM children WHERE self != toObjectId"); return new SqlSelector(getExpSchema(),sql).getArrayList(InnerResult.class); } diff --git a/experiment/src/org/labkey/experiment/api/ExperimentStressTest.java b/experiment/src/org/labkey/experiment/api/ExperimentStressTest.java index 8cd654a85db..449937c1dbb 100644 --- a/experiment/src/org/labkey/experiment/api/ExperimentStressTest.java +++ b/experiment/src/org/labkey/experiment/api/ExperimentStressTest.java @@ -17,13 +17,11 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.junit.Assume; import org.junit.Before; import org.junit.Test; import org.labkey.api.collections.CaseInsensitiveHashMap; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; -import org.labkey.api.data.CoreSchema; import org.labkey.api.data.DbScope; import org.labkey.api.data.TableInfo; import org.labkey.api.exp.api.ExpSampleType; @@ -182,14 +180,6 @@ public void sampleTypeInsertsWithAliquot() throws Throwable private void _sampleTypeInserts(RunMode mode) throws Throwable { - /* - * Deadlock on recompute introduced by Issue 47033 has been fixed by Issue 47246. - * The tests are currently passing when run locally using sql server. - * However, there are more deadlocks with sql server when run on TC, now on ExperimentRun table. - */ - Assume.assumeFalse("Issue 47033: Test does not yet pass on SQL Server. Skipping.", - CoreSchema.getInstance().getSqlDialect().isSqlServer()); - LOG.info("** starting sample type insert test {}", mode._description); final User user = TestContext.get().getUser(); final Container c = JunitUtil.getTestContainer(); diff --git a/experiment/src/org/labkey/experiment/api/SampleTypeServiceImpl.java b/experiment/src/org/labkey/experiment/api/SampleTypeServiceImpl.java index e1aeec93ab5..89e41e0599e 100644 --- a/experiment/src/org/labkey/experiment/api/SampleTypeServiceImpl.java +++ b/experiment/src/org/labkey/experiment/api/SampleTypeServiceImpl.java @@ -1633,38 +1633,15 @@ public int recomputeSamplesRollup( SQLFragment quickRollUpSql = null; - if (tableInfo.getSchema().getSqlDialect().isSqlServer()) - { - /* - * SqlServer needs to specify the alias in the FROM clause, and use that alias as the target of the update. - */ - quickRollUpSql = new SQLFragment("UPDATE exp.material SET \n") - .append("aliquotvolume = ROUND(CAST(COALESCE(stats.total_volume, 0) AS NUMERIC(38,12)) , ?),\n").add(precisionScale) - .append("aliquotunit = stats.common_unit,\n") - .append("availablealiquotvolume = ROUND(CAST(COALESCE(stats.avail_volume, 0) AS NUMERIC(38,12)), ?)\n").add(precisionScale) - .append("FROM exp.material m INNER JOIN (") - .append(statsSql) - .append(") AS stats\n") - .append("ON m.rowid = stats.rootmaterialrowid" - ); - } - else - { - /* - * Alias usage: PostgreSQL allows you to use an alias in the UPDATE clause itself - * Type casting: PostgreSQL uses ::NUMERIC for type casting. - * JOIN condition: The WHERE clause is used for joining the tables instead of an INNER JOIN with ON. - */ - quickRollUpSql = new SQLFragment("UPDATE exp.material AS m SET \n") - .append("aliquotvolume = ROUND(COALESCE(stats.total_volume, 0)::NUMERIC, ?),\n").add(precisionScale) - .append("aliquotunit = stats.common_unit,\n") - .append("availablealiquotvolume = ROUND(COALESCE(stats.avail_volume, 0)::NUMERIC, ?)\n").add(precisionScale) - .append("FROM (") - .append(statsSql) - .append(") AS stats\n") - .append("WHERE m.rowid = stats.rootmaterialrowid" - ); - } + quickRollUpSql = new SQLFragment("UPDATE exp.material AS m SET \n") + .append("aliquotvolume = ROUND(COALESCE(stats.total_volume, 0)::NUMERIC, ?),\n").add(precisionScale) + .append("aliquotunit = stats.common_unit,\n") + .append("availablealiquotvolume = ROUND(COALESCE(stats.avail_volume, 0)::NUMERIC, ?)\n").add(precisionScale) + .append("FROM (") + .append(statsSql) + .append(") AS stats\n") + .append("WHERE m.rowid = stats.rootmaterialrowid" + ); new SqlExecutor(tableInfo.getSchema()).execute(quickRollUpSql); diff --git a/experiment/src/org/labkey/experiment/api/property/DomainImpl.java b/experiment/src/org/labkey/experiment/api/property/DomainImpl.java index b07d0391a77..bf7d16d2d7d 100644 --- a/experiment/src/org/labkey/experiment/api/property/DomainImpl.java +++ b/experiment/src/org/labkey/experiment/api/property/DomainImpl.java @@ -444,7 +444,7 @@ public void lockForUpdateDelete(DbSchema lockSchema) lock.lock(); // CONSIDER verify table exists: SELECT 1 FROM pg_tables WHERE schemaname = ? AND tablename = ? - if (null != getStorageTableName() && lockSchema.getSqlDialect().isPostgreSQL()) + if (null != getStorageTableName()) { SQLFragment lockSQL = new SQLFragment().append("LOCK TABLE ").appendDottedIdentifiers(getDomainKind().getStorageSchemaName(), getStorageTableName()).append(" IN ACCESS EXCLUSIVE MODE").appendEOS().append("\n"); new SqlExecutor(lockSchema).execute(lockSQL); @@ -623,15 +623,6 @@ public void save(User user, boolean allowAddBaseProperty, boolean saveOnlyIfNotE try (DbScope.Transaction transaction = scope.ensureTransaction(domainLock)) { - // This is a pretty heavy-handed way to fix a deadlock problem, but it works - // CONSIDER: another approach might be to fine tune the filters/indexes used in the Table.insert/OntologyManager.getDomainDescriptor calls - // or using LSID as the primary key on DomainDescriptor? - if (scope.getSqlDialect().isSqlServer()) - { - String sql = "SELECT * FROM " + OntologyManager.getTinfoDomainDescriptor() + " WITH (UPDLOCK)"; - new SqlSelector(schema, sql).getArrayList(DomainDescriptor.class); - } - // Issue 32406: Need to capture because _new changes during the process boolean isDomainNew = isNew(); if (saveOnlyIfNotExists && !isDomainNew) diff --git a/experiment/src/org/labkey/experiment/api/property/DomainPropertyImpl.java b/experiment/src/org/labkey/experiment/api/property/DomainPropertyImpl.java index 0d561c369d6..e2467a0097c 100644 --- a/experiment/src/org/labkey/experiment/api/property/DomainPropertyImpl.java +++ b/experiment/src/org/labkey/experiment/api/property/DomainPropertyImpl.java @@ -904,7 +904,7 @@ else if (newType == PropertyType.MULTI_CHOICE || oldType == PropertyType.MULTI_C } TableInfo table = domainKind.getTableInfo(user, getContainer(), _domain, ContainerFilter.getUnsafeEverythingFilter()); - if (table != null && _pdOld.getPropertyType() != null && table.getSchema().getSqlDialect().isPostgreSQL()) + if (table != null && _pdOld.getPropertyType() != null) QueryChangeListener.QueryPropertyChange.handleColumnTypeChange(_pdOld, _pd, SchemaKey.fromString(table.getUserSchema().getSchemaName()), table.getName(), user, getContainer()); } else if (propResized) diff --git a/experiment/src/org/labkey/experiment/api/property/StorageNameGenerator.java b/experiment/src/org/labkey/experiment/api/property/StorageNameGenerator.java index 997d4168c6f..2241cc31e96 100644 --- a/experiment/src/org/labkey/experiment/api/property/StorageNameGenerator.java +++ b/experiment/src/org/labkey/experiment/api/property/StorageNameGenerator.java @@ -21,7 +21,6 @@ import org.junit.Test; import org.labkey.api.collections.CaseInsensitiveHashSet; import org.labkey.api.data.DbScope; -import org.labkey.api.data.dialect.PostgreSqlService; import org.labkey.api.data.dialect.SqlDialect; import org.labkey.api.exp.OntologyManager; import org.labkey.api.util.StringUtilsLabKey; @@ -48,8 +47,7 @@ public class StorageNameGenerator public StorageNameGenerator(@NotNull SqlDialect dialect) { - // GitHub Issue 869: Create SQL Server storage names using PostgreSQL's rules to ensure all tables and columns can migrate - _dialect = dialect.isSqlServer() ? PostgreSqlService.get().getDialect() : dialect; + _dialect = dialect; } public String claimName(String name) diff --git a/experiment/src/org/labkey/experiment/api/property/StorageProvisionerImpl.java b/experiment/src/org/labkey/experiment/api/property/StorageProvisionerImpl.java index 21e4632f511..ad584e9bfaa 100644 --- a/experiment/src/org/labkey/experiment/api/property/StorageProvisionerImpl.java +++ b/experiment/src/org/labkey/experiment/api/property/StorageProvisionerImpl.java @@ -1417,15 +1417,6 @@ else if (hardColumnNames.remove(propDescriptor.getStorageColumnName())) status.hasProblem = true; } - // Ignore the hashed columns generated for unique constraint over large text columns required for SQLServer - // Unfortunately, the domain doesn't record the intended unique indices, so we'll just ignore all columns that have the "_hashed_" prefix. - var dialect = getSqlDialect(domain); - if (getSqlDialect(domain).isSqlServer() && domainProp.getJdbcType().isText()) - { - String hashedColumnName = PropertyStorageSpec.HASHED_COLUMN_PREFIX + propDescriptor.getName(); - hardColumnNames.remove(hashedColumnName); - } - String mvColName = PropertyStorageSpec.getMvIndicatorDisplayColumnName(propDescriptor); if (hardColumnNames.remove(mvColName)) // hashed status.mvColName = mvColName; diff --git a/experiment/test/src/org/labkey/test/tests/experiment/ProvenanceAssayHelper.java b/experiment/test/src/org/labkey/test/tests/experiment/ProvenanceAssayHelper.java index 6091fa3f535..851727aef87 100644 --- a/experiment/test/src/org/labkey/test/tests/experiment/ProvenanceAssayHelper.java +++ b/experiment/test/src/org/labkey/test/tests/experiment/ProvenanceAssayHelper.java @@ -33,7 +33,6 @@ import org.labkey.test.pages.ReactAssayDesignerPage; import org.labkey.test.params.FieldDefinition; import org.labkey.test.params.experiment.SampleTypeDefinition; -import org.labkey.test.util.PostgresOnlyTest; import org.labkey.test.util.SampleTypeHelper; import java.io.File; @@ -42,7 +41,7 @@ import java.util.List; import java.util.Map; -public abstract class ProvenanceAssayHelper extends BaseWebDriverTest implements PostgresOnlyTest +public abstract class ProvenanceAssayHelper extends BaseWebDriverTest { protected static final String PROVENANCE_DATA_FILE = "AssayImportProvenanceRun.xls"; diff --git a/filecontent/module.properties b/filecontent/module.properties index fb54e858f5c..9abe38cb040 100644 --- a/filecontent/module.properties +++ b/filecontent/module.properties @@ -7,5 +7,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/filecontent/resources/schemas/dbscripts/sqlserver/filecontent-0.00-14.20.sql b/filecontent/resources/schemas/dbscripts/sqlserver/filecontent-0.00-14.20.sql deleted file mode 100644 index da5c8db445e..00000000000 --- a/filecontent/resources/schemas/dbscripts/sqlserver/filecontent-0.00-14.20.sql +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2016-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* filecontent-0.00-12.10.sql */ - -CREATE SCHEMA filecontent; -GO - -CREATE TABLE filecontent.FileRoots -( - RowId INT IDENTITY(1, 1), - Container ENTITYID NOT NULL, - Path NVARCHAR(255), - Type NVARCHAR(50), - Properties TEXT, - - Enabled BIT NOT NULL DEFAULT 1, - UseDefault BIT NOT NULL DEFAULT 0, - - CONSTRAINT PK_FileRoots PRIMARY KEY (RowId) -); - -/* filecontent-14.10-14.20.sql */ - -DELETE FROM prop.properties WHERE name = 'experimentalFeature.dragDropUpload'; - -DELETE FROM filecontent.FileRoots WHERE RowId NOT IN (SELECT MIN(RowId) FROM filecontent.FileRoots GROUP BY Container); -ALTER TABLE filecontent.FileRoots ADD CONSTRAINT Container_Type_Key UNIQUE (Container, Type); \ No newline at end of file diff --git a/filecontent/src/org/labkey/filecontent/FileRootMaintenanceTask.java b/filecontent/src/org/labkey/filecontent/FileRootMaintenanceTask.java index 47ac24c6665..aa14e5c53bf 100644 --- a/filecontent/src/org/labkey/filecontent/FileRootMaintenanceTask.java +++ b/filecontent/src/org/labkey/filecontent/FileRootMaintenanceTask.java @@ -78,7 +78,7 @@ public void run(Logger log) String updateLastCrawledSql = "UPDATE " + containers.getSelectName() + " SET FileRootLastCrawled = ? WHERE EntityId = ?"; String updateLastCrawledAndSizeSql = "UPDATE " + containers.getSelectName() + " SET FileRootLastCrawled = ?, FileRootSize = ? WHERE EntityId = ?"; SqlExecutor executor = new SqlExecutor(containers.getSchema()); - String orderBy = " ORDER BY FileRootLastCrawled" + (containers.getSqlDialect().isPostgreSQL() ? " NULLS FIRST" : ""); + String orderBy = " ORDER BY FileRootLastCrawled NULLS FIRST"; SQLFragment selectSql = new SQLFragment("SELECT RowId, EntityId, FileRootSize FROM " + containers.getSelectName() + orderBy); new SqlSelector(containers.getSchema(), selectSql) diff --git a/issues/module.properties b/issues/module.properties index 169fc450c1d..135903e0079 100644 --- a/issues/module.properties +++ b/issues/module.properties @@ -10,5 +10,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/issues/resources/schemas/dbscripts/sqlserver/issues-0.00-19.10.sql b/issues/resources/schemas/dbscripts/sqlserver/issues-0.00-19.10.sql deleted file mode 100644 index a491b3603b4..00000000000 --- a/issues/resources/schemas/dbscripts/sqlserver/issues-0.00-19.10.sql +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2018-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* issues-0.00-10.20.sql */ - -CREATE SCHEMA issues; -GO - -CREATE TABLE issues.Issues -( - _ts TIMESTAMP, - Container ENTITYID NOT NULL, - IssueId INT IDENTITY(1,1) NOT NULL, - EntityId ENTITYID DEFAULT NEWID(), -- used for attachments - Duplicate INT, - LastIndexed DATETIME NULL, - - CONSTRAINT PK_Issues PRIMARY KEY (IssueId) -); - -CREATE TABLE issues.Comments -( - --EntityId ENTITYID DEFAULT NEWID(), - CommentId INT IDENTITY(1,1), - IssueId INT, - CreatedBy USERID, - Created DATETIME DEFAULT GETDATE(), - Comment NTEXT, - EntityId ENTITYID, - - CONSTRAINT PK_Comments PRIMARY KEY (IssueId, CommentId), - CONSTRAINT FK_Comments_Issues FOREIGN KEY (IssueId) REFERENCES issues.Issues(IssueId) -); - - -CREATE TABLE issues.IssueKeywords -( - Container ENTITYID NOT NULL, - Type INT NOT NULL, -- area or milestone (or whatever) - Keyword VARCHAR(255) NOT NULL, - "Default" BIT NOT NULL DEFAULT 0, - - CONSTRAINT PK_IssueKeywords PRIMARY KEY (Container, Type, Keyword) -); - - -CREATE TABLE issues.EmailPrefs -( - Container ENTITYID, - UserId USERID, - EmailOption INT NOT NULL, - - CONSTRAINT PK_EmailPrefs PRIMARY KEY (Container, UserId), - CONSTRAINT FK_EmailPrefs_Containers FOREIGN KEY (Container) REFERENCES core.Containers (EntityId), - CONSTRAINT FK_EmailPrefs_Principals FOREIGN KEY (UserId) REFERENCES core.Principals (UserId), -); - -/* issues-12.30-13.10.sql */ - --- Move the column settings from properties to a proper table, add column permissions -CREATE TABLE issues.CustomColumns -( - Container ENTITYID NOT NULL, - Name VARCHAR(50) NOT NULL, - Caption VARCHAR(200) NOT NULL, - PickList BIT NOT NULL DEFAULT 0, - Permission VARCHAR(300) NOT NULL, - - CONSTRAINT PK_CustomColumns PRIMARY KEY (Container, Name) -); - -INSERT INTO issues.CustomColumns - SELECT ObjectId AS Container, LOWER(Name), Value AS Caption, - CASE WHEN CHARINDEX - ( - Name, (SELECT Value FROM prop.PropertyEntries pl WHERE Category = 'IssuesCaptions' - AND Name = 'pickListColumns' AND pe.ObjectId = pl.ObjectId) - ) > 0 THEN 1 ELSE 0 END AS PickList, 'org.labkey.api.security.permissions.ReadPermission' AS Permission - FROM prop.PropertyEntries pe WHERE Category = 'IssuesCaptions' AND Name <> 'pickListColumns'; - --- These properties have been moved to a dedicated table -DELETE FROM prop.Properties WHERE "Set" IN (SELECT "Set" FROM prop.PropertySets WHERE Category = 'IssuesCaptions'); -DELETE FROM prop.PropertySets WHERE Category = 'IssuesCaptions'; - -/* issues-14.10-14.20.sql */ - -DELETE FROM prop.properties WHERE name = 'experimentalFeature.issuesactivity'; - -CREATE TABLE issues.RelatedIssues -( - IssueId INT, - RelatedIssueId INT, - - CONSTRAINT PK_RelatedIssues PRIMARY KEY (IssueId, RelatedIssueId), - CONSTRAINT FK_RelatedIssues_Issues_IssueId FOREIGN KEY (IssueId) REFERENCES issues.Issues(IssueId), - CONSTRAINT FK_RelatedIssues_Issues_RelatedIssueId FOREIGN KEY (RelatedIssueId) REFERENCES issues.Issues(IssueId) -); -CREATE INDEX IX_RelatedIssues_IssueId ON issues.RelatedIssues (IssueId); -CREATE INDEX IX_RelatedIssues_RelatedIssueId ON issues.RelatedIssues (RelatedIssueId); -GO - -/* issues-16.10-16.20.sql */ - -CREATE SCHEMA IssueDef; -GO - -CREATE TABLE issues.IssueDef -( - RowId INT IDENTITY(1, 1) NOT NULL, - Name NVARCHAR(200) NOT NULL, - - Container ENTITYID NOT NULL, - Created DATETIME, - Modified DATETIME, - CreatedBy INTEGER, - ModifiedBy INTEGER, - - CONSTRAINT PK_IssueDef PRIMARY KEY (RowId), - CONSTRAINT UQ_IssueDef_Container_Name UNIQUE (Name, Container) -); - --- Rename from IssueDef to IssueListDef -EXEC sp_rename 'issues.IssueDef', 'IssueListDef' -GO - -ALTER TABLE issues.Issues ADD IssueDefId INTEGER; -ALTER TABLE issues.Issues ADD CONSTRAINT FK_IssueListDef_IssueDefId_RowId FOREIGN KEY (IssueDefId) REFERENCES issues.IssueListDef(RowId); - -ALTER TABLE issues.IssueListDef ADD Label NVARCHAR(200); -GO -UPDATE issues.IssueListDef SET Label = Name; -ALTER TABLE issues.IssueListDef ALTER COLUMN Label NVARCHAR(200) NOT NULL; - -/* issues-16.20-16.30.sql */ - -ALTER TABLE issues.issuelistdef ADD kind NVARCHAR(200) NOT NULL DEFAULT 'IssueDefinition'; - -/* issues-18.30-19.10.sql */ - -DROP TABLE issues.IssueKeywords; -DROP TABLE issues.CustomColumns; \ No newline at end of file diff --git a/issues/resources/schemas/dbscripts/sqlserver/issues-25.000-25.001.sql b/issues/resources/schemas/dbscripts/sqlserver/issues-25.000-25.001.sql deleted file mode 100644 index fdefbb712d5..00000000000 --- a/issues/resources/schemas/dbscripts/sqlserver/issues-25.000-25.001.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- This index overlaps with pk_relatedissues -DROP INDEX ix_relatedissues_issueid ON issues.RelatedIssues; diff --git a/list/module.properties b/list/module.properties index daf8d4a594d..7ed64ce1648 100644 --- a/list/module.properties +++ b/list/module.properties @@ -13,5 +13,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/list/resources/schemas/dbscripts/sqlserver/list-0.000-22.000.sql b/list/resources/schemas/dbscripts/sqlserver/list-0.000-22.000.sql deleted file mode 100644 index aaedcbed8c4..00000000000 --- a/list/resources/schemas/dbscripts/sqlserver/list-0.000-22.000.sql +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* list-13.10-13.20.sql */ - -CREATE SCHEMA list; -GO - -EXEC core.fn_dropifexists 'indexinteger', 'exp', 'TABLE'; -EXEC core.fn_dropifexists 'indexvarchar', 'exp', 'TABLE'; -EXEC core.fn_dropifexists 'list', 'exp', 'CONSTRAINT', 'UQ_RowId'; - -IF EXISTS (SELECT 1 FROM sys.columns WHERE Name = N'rowid' AND Object_ID = OBJECT_ID('exp.list')) - BEGIN - ALTER TABLE [exp].list DROP COLUMN rowid; - END diff --git a/list/src/org/labkey/list/model/ListImporter.java b/list/src/org/labkey/list/model/ListImporter.java index 90c3b1882e0..790bac2b9e3 100644 --- a/list/src/org/labkey/list/model/ListImporter.java +++ b/list/src/org/labkey/list/model/ListImporter.java @@ -241,18 +241,6 @@ private boolean processSingle(VirtualFile sourceDir, ListDefinition def, String } } - // pre-process - if (supportAI) - { - SqlDialect dialect = ti.getSqlDialect(); - - if (dialect.isSqlServer()) - { - SQLFragment check = new SQLFragment("SET IDENTITY_INSERT ").append(tableName).append(" ON\n"); - new SqlExecutor(ti.getSchema()).execute(check); - } - } - def.importListItems(user, c, loader, batchErrors, sourceDir.getDir(FileUtil.makeLegalName(def.getName())), null, supportAI, LookupResolutionType.primaryKey, _importContext.useMerge() ? QueryUpdateService.InsertOption.MERGE : QueryUpdateService.InsertOption.IMPORT); } @@ -267,70 +255,45 @@ private boolean processSingle(VirtualFile sourceDir, ListDefinition def, String SqlDialect dialect = ti.getSqlDialect(); // If auto-increment based need to reset the sequence counter on the DB - if (dialect.isPostgreSQL()) + String src = ti.getColumn(def.getKeyName()).getJdbcDefaultValue(); + if (null != src) { - String src = ti.getColumn(def.getKeyName()).getJdbcDefaultValue(); - if (null != src) + SQLFragment keyupdate; + + // To best support crazy column names, reuse the regclass in the nextval() call when present + if (src.startsWith("nextval(") && src.endsWith("::regclass)")) { - SQLFragment keyupdate; - - // To best support crazy column names, reuse the regclass in the nextval() call when present - if (src.startsWith("nextval(") && src.endsWith("::regclass)")) - { - String setVal = src.replace("nextval(", "setval("); - setVal = setVal.replace("::regclass)", "::regclass, "); - keyupdate = new SQLFragment("SELECT ").append(SQLFragment.unsafe(setVal)); - } - else - { - // In case there are sequences in the wild with different syntax, fall back on - // our previous strategy - String sequence = ""; - - int start = src.indexOf('\''); - int end = src.lastIndexOf('\''); - - if (end > start) - - sequence = src.substring(start + 1, end); - if (!sequence.toLowerCase().startsWith("list.")) - sequence = "list." + sequence; - keyupdate = new SQLFragment("SELECT setval(").appendStringLiteral(sequence, dialect); - } - - String keyStorageColName = def.getDomain().getPropertyByName(def.getKeyName()).getPropertyDescriptor().getStorageColumnName(); - keyupdate.append(" coalesce((SELECT MAX(").appendIdentifier(dialect.makeDatabaseIdentifier(keyStorageColName.toLowerCase())).append(")+1 FROM ").append(tableName); - keyupdate.append("), 1), false)"); - new SqlExecutor(ti.getSchema()).execute(keyupdate); + String setVal = src.replace("nextval(", "setval("); + setVal = setVal.replace("::regclass)", "::regclass, "); + keyupdate = new SQLFragment("SELECT ").append(SQLFragment.unsafe(setVal)); } + else + { + // In case there are sequences in the wild with different syntax, fall back on + // our previous strategy + String sequence = ""; - } - else if (dialect.isSqlServer()) - { - SQLFragment check = new SQLFragment("SET IDENTITY_INSERT ").append(tableName).append(" OFF\n"); - new SqlExecutor(ti.getSchema()).execute(check); - supportAI = false; // reset in order to avoid setting IDENTITY_INSERT to OFF again in the finally block below. + int start = src.indexOf('\''); + int end = src.lastIndexOf('\''); + + if (end > start) + + sequence = src.substring(start + 1, end); + if (!sequence.toLowerCase().startsWith("list.")) + sequence = "list." + sequence; + keyupdate = new SQLFragment("SELECT setval(").appendStringLiteral(sequence, dialect); + } + + String keyStorageColName = def.getDomain().getPropertyByName(def.getKeyName()).getPropertyDescriptor().getStorageColumnName(); + keyupdate.append(" coalesce((SELECT MAX(").appendIdentifier(dialect.makeDatabaseIdentifier(keyStorageColName.toLowerCase())).append(")+1 FROM ").append(tableName); + keyupdate.append("), 1), false)"); + new SqlExecutor(ti.getSchema()).execute(keyupdate); } } transaction.commit(); } } - // any errors during an insert in the above block will keep IDENTITY_INSERT set to ON - so setting it to OFF in the finally block. - // Refer to Issue 32667 for more details. - finally - { - if (supportAI) - { - SqlDialect dialect = ti.getSqlDialect(); - - if (dialect.isSqlServer()) - { - SQLFragment check = new SQLFragment("SET IDENTITY_INSERT ").append(tableName).append(" OFF\n"); - new SqlExecutor(ti.getSchema()).execute(check); - } - } - } } else if (_importContext.isTriggeredReload()) { diff --git a/mothership/test/src/org/labkey/test/tests/mothership/InProductMessagingTest.java b/mothership/test/src/org/labkey/test/tests/mothership/InProductMessagingTest.java index 9040618aa38..1bac2324225 100644 --- a/mothership/test/src/org/labkey/test/tests/mothership/InProductMessagingTest.java +++ b/mothership/test/src/org/labkey/test/tests/mothership/InProductMessagingTest.java @@ -25,7 +25,6 @@ import org.labkey.test.categories.Daily; import org.labkey.test.pages.mothership.EditUpgradeMessagePage; import org.labkey.test.util.OptionalFeatureHelper; -import org.labkey.test.util.PostgresOnlyTest; import org.labkey.test.util.TestUser; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.ui.ExpectedConditions; @@ -41,7 +40,7 @@ @Category({Daily.class}) -public class InProductMessagingTest extends BaseWebDriverTest implements PostgresOnlyTest +public class InProductMessagingTest extends BaseWebDriverTest { private static final TestUser TEST_AUTHOR = new TestUser("inproductmessageauthor@test.test"); diff --git a/mothership/test/src/org/labkey/test/tests/mothership/MothershipReportTest.java b/mothership/test/src/org/labkey/test/tests/mothership/MothershipReportTest.java index d5df737d888..4b95cbb7808 100644 --- a/mothership/test/src/org/labkey/test/tests/mothership/MothershipReportTest.java +++ b/mothership/test/src/org/labkey/test/tests/mothership/MothershipReportTest.java @@ -33,7 +33,6 @@ import org.labkey.test.pages.core.admin.CustomizeSitePage; import org.labkey.test.pages.mothership.ShowInstallationDetailPage; import org.labkey.test.pages.test.TestActions; -import org.labkey.test.util.PostgresOnlyTest; import org.labkey.test.util.mothership.MothershipHelper; import java.io.File; @@ -55,7 +54,7 @@ @Category({Daily.class}) @BaseWebDriverTest.ClassTimeout(minutes = 4) @OrderWith(Alphanumeric.class) -public class MothershipReportTest extends BaseWebDriverTest implements PostgresOnlyTest +public class MothershipReportTest extends BaseWebDriverTest { private MothershipHelper _mothershipHelper; diff --git a/mothership/test/src/org/labkey/test/tests/mothership/MothershipTest.java b/mothership/test/src/org/labkey/test/tests/mothership/MothershipTest.java index a1276151a27..42bd322f774 100644 --- a/mothership/test/src/org/labkey/test/tests/mothership/MothershipTest.java +++ b/mothership/test/src/org/labkey/test/tests/mothership/MothershipTest.java @@ -34,7 +34,6 @@ import org.labkey.test.pages.mothership.StackTraceDetailsPage; import org.labkey.test.util.ApiPermissionsHelper; import org.labkey.test.util.PermissionsHelper.MemberType; -import org.labkey.test.util.PostgresOnlyTest; import org.labkey.test.util.mothership.MothershipHelper; import java.util.ArrayList; @@ -56,7 +55,7 @@ @Category({Daily.class}) @BaseWebDriverTest.ClassTimeout(minutes = 6) -public class MothershipTest extends BaseWebDriverTest implements PostgresOnlyTest +public class MothershipTest extends BaseWebDriverTest { private static final String ASSIGNEE = "assignee@mothership.test"; private static final String ASSIGNEE2 = "assignee2@mothership.test"; diff --git a/pipeline/module.properties b/pipeline/module.properties index f4b3047a989..c46c658e251 100644 --- a/pipeline/module.properties +++ b/pipeline/module.properties @@ -11,5 +11,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/pipeline/resources/schemas/dbscripts/sqlserver/pipeline-0.000-24.000.sql b/pipeline/resources/schemas/dbscripts/sqlserver/pipeline-0.000-24.000.sql deleted file mode 100644 index b83cecd3ac4..00000000000 --- a/pipeline/resources/schemas/dbscripts/sqlserver/pipeline-0.000-24.000.sql +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2018-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE SCHEMA pipeline; -GO - -CREATE TABLE pipeline.StatusFiles -( - _ts TIMESTAMP, - CreatedBy USERID, - Created DATETIME DEFAULT GETDATE(), - ModifiedBy USERID, - Modified DATETIME DEFAULT GETDATE(), - - Container ENTITYID NOT NULL, - EntityId ENTITYID NOT NULL, - - RowId INT IDENTITY(1,1) NOT NULL, - Status NVARCHAR(100), - Info NVARCHAR(1024), - FilePath NVARCHAR(1024), - Email NVARCHAR(255), - - Description NVARCHAR(255), - DataUrl NVARCHAR(1024), - Job UNIQUEIDENTIFIER, - Provider NVARCHAR(255), - HadError BIT NOT NULL DEFAULT 0, - - JobParent UNIQUEIDENTIFIER, - JobStore NTEXT, - ActiveTaskId NVARCHAR(255), - - CONSTRAINT FK_StatusFiles_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId), - CONSTRAINT UQ_StatusFiles_FilePath UNIQUE (FilePath), - CONSTRAINT PK_StatusFiles PRIMARY KEY NONCLUSTERED (RowId), -- Clustered on Container below - CONSTRAINT UQ_StatusFiles_Job UNIQUE (Job), - CONSTRAINT FK_StatusFiles_JobParent FOREIGN KEY (JobParent) REFERENCES pipeline.StatusFiles(Job) -); -CREATE CLUSTERED INDEX IX_StatusFiles_Container_JobParent ON pipeline.StatusFiles (Container ASC, JobParent ASC); - -ALTER TABLE pipeline.StatusFiles ADD ActiveHostName NVARCHAR(255) NULL; -ALTER TABLE pipeline.StatusFiles ADD TaskPipelineId NVARCHAR(255); - -CREATE TABLE pipeline.PipelineRoots -( - _ts TIMESTAMP, - CreatedBy USERID, - Created DATETIME DEFAULT GETDATE(), - ModifiedBy USERID, - Modified DATETIME DEFAULT GETDATE(), - - Container ENTITYID NOT NULL, - EntityId ENTITYID NOT NULL, - - PipelineRootId INT IDENTITY(1,1) NOT NULL, - Path NVARCHAR(300) NOT NULL, - Providers VARCHAR(100), - Type NVARCHAR(255) NOT NULL DEFAULT 'PRIMARY', - - KeyBytes IMAGE, - CertBytes IMAGE, - KeyPassword NVARCHAR(32), - - Searchable BIT NOT NULL DEFAULT 0, - - CONSTRAINT PK_PipelineRoots PRIMARY KEY (PipelineRootId) -); - -ALTER TABLE pipeline.PipelineRoots ADD SupplementalPath NVARCHAR(300); - -ALTER TABLE pipeline.PipelineRoots DROP COLUMN KeyBytes; -ALTER TABLE pipeline.PipelineRoots DROP COLUMN CertBytes; -ALTER TABLE pipeline.PipelineRoots DROP COLUMN KeyPassword; - -DELETE FROM pipeline.PipelineRoots WHERE Container NOT IN (SELECT EntityId FROM core.Containers); - -ALTER TABLE pipeline.PipelineRoots ADD CONSTRAINT FK_PipelineRoots_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); - -ALTER TABLE pipeline.PipelineRoots ADD CONSTRAINT UQ_PipelineRoots_Container_Type UNIQUE (Container, Type); - -CREATE TABLE pipeline.TriggerConfigurations -( - RowId INT IDENTITY(1, 1) NOT NULL, - Container ENTITYID NOT NULL, - Created DATETIME, - CreatedBy USERID, - Modified DATETIME, - ModifiedBy USERID, - - Name NVARCHAR(255) NOT NULL, - Description NVARCHAR(MAX), - Type NVARCHAR(255) NOT NULL, - Enabled BIT, - Configuration NVARCHAR(MAX), - PipelineId NVARCHAR(255) NOT NULL, - LastChecked DATETIME, - - CONSTRAINT PK_TriggerConfigurations PRIMARY KEY (RowId), - CONSTRAINT FK_TriggerConfigurations_Container FOREIGN KEY (Container) REFERENCES core.Containers (ENTITYID), - CONSTRAINT UQ_TriggerConfigurations_Name UNIQUE (Container, Name) -); - -ALTER TABLE pipeline.TriggerConfigurations ADD customConfiguration NVARCHAR(MAX); - -CREATE TABLE pipeline.TriggeredFiles -( - RowId INT IDENTITY(1,1) NOT NULL, - Container ENTITYID NOT NULL, - TriggerId INT NOT NULL, - FilePath NVARCHAR(1000) NOT NULL, - LastRun DATETIME, - - CONSTRAINT PK_TriggeredFiles PRIMARY KEY (RowId), - CONSTRAINT FK_TriggeredFiles_TriggerId FOREIGN KEY (TriggerId) REFERENCES pipeline.TriggerConfigurations(RowId), - CONSTRAINT FK_TriggeredFiles_Container FOREIGN KEY (Container) REFERENCES core.Containers (ENTITYID), - CONSTRAINT UQ_TriggeredFiles_Container_TriggerId_FilePath UNIQUE (Container, TriggerId, FilePath) -); - --- Make pipeline.StatusFiles.FilePath NOT NULL, dropping and recreating unique constraint -ALTER TABLE pipeline.StatusFiles DROP CONSTRAINT UQ_StatusFiles_FilePath; -ALTER TABLE pipeline.StatusFiles ALTER COLUMN FilePath NVARCHAR(1024) NOT NULL; -ALTER TABLE pipeline.StatusFiles ADD CONSTRAINT UQ_StatusFiles_FilePath UNIQUE (FilePath); diff --git a/query/module.properties b/query/module.properties index e6cf64087b8..a7c55605d1d 100644 --- a/query/module.properties +++ b/query/module.properties @@ -5,5 +5,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/query/resources/schemas/dbscripts/sqlserver/query-0.00-19.10.sql b/query/resources/schemas/dbscripts/sqlserver/query-0.00-19.10.sql deleted file mode 100644 index b435b585649..00000000000 --- a/query/resources/schemas/dbscripts/sqlserver/query-0.00-19.10.sql +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (c) 2016-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE SCHEMA query; -GO - -CREATE TABLE query.QueryDef -( - QueryDefId INT IDENTITY(1, 1) NOT NULL, - EntityId UNIQUEIDENTIFIER NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - - Container UNIQUEIDENTIFIER NOT NULL, - Name NVARCHAR(200) NOT NULL, - "Schema" NVARCHAR(200) NOT NULL, - Sql NTEXT, - MetaData NTEXT, - Description NTEXT, - SchemaVersion FLOAT NOT NULL, - Flags INT NOT NULL, - CONSTRAINT PK_QueryDef PRIMARY KEY (QueryDefId), - CONSTRAINT UQ_QueryDef UNIQUE (Container, "Schema", Name) -); - -CREATE TABLE query.CustomView -( - CustomViewId INT IDENTITY(1,1) NOT NULL, - EntityId UNIQUEIDENTIFIER NOT NULL, - Created DATETIME NOT NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - "Schema" NVARCHAR(200) NOT NULL, - QueryName NVARCHAR(200) NOT NULL, - - Container UNIQUEIDENTIFIER NOT NULL, - Name NVARCHAR(200) NULL, - CustomViewOwner INT NULL, - Columns NTEXT, - Filter NTEXT, - Flags INT NOT NULL, - CONSTRAINT PK_CustomView PRIMARY KEY (CustomViewId), - CONSTRAINT UQ_CustomView UNIQUE (Container, "Schema", QueryName, CustomViewOwner, Name) -); - -CREATE TABLE query.ExternalSchema -( - ExternalSchemaId INT IDENTITY(1,1) NOT NULL, - EntityId UNIQUEIDENTIFIER NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - - Container UNIQUEIDENTIFIER NOT NULL, - DataSource NVARCHAR(50) NOT NULL, - UserSchemaName NVARCHAR(50) NOT NULL, - SourceSchemaName NVARCHAR(50) NULL, - Editable BIT NOT NULL DEFAULT 0, - MetaData NTEXT NULL, - Indexable BIT NOT NULL DEFAULT 1, - Tables VARCHAR(8000) NULL, -- Comma-separated list of tables to expose; null represents all tables - - CONSTRAINT PK_DbUserSchema PRIMARY KEY(ExternalSchemaId), - CONSTRAINT UQ_ExternalSchema UNIQUE(Container,UserSchemaName) -); - -ALTER TABLE query.ExternalSchema - ADD SchemaType NVARCHAR(50) NOT NULL CONSTRAINT DF_ExternalSchema_SchemaType DEFAULT 'external'; - -ALTER TABLE query.ExternalSchema - ADD SchemaTemplate NVARCHAR(50); - --- Require NOT NULL SourceSchemaName and Tables when SchemaTemplate IS NULL -ALTER TABLE query.ExternalSchema - ADD CONSTRAINT "CK_SchemaTemplate" - CHECK (SchemaTemplate IS NOT NULL OR (SchemaTemplate IS NULL AND SourceSchemaName IS NOT NULL AND Tables IS NOT NULL)); - -ALTER TABLE query.ExternalSchema - ADD FastCacheRefresh BIT NOT NULL CONSTRAINT DF_ExternalSchema_FastCache DEFAULT 0; - -CREATE TABLE query.QuerySnapshotDef -( - RowId INT IDENTITY(1,1) NOT NULL, - QueryDefId INT NULL, - - EntityId ENTITYID NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - Container ENTITYID NOT NULL, - "Schema" NVARCHAR(50) NOT NULL, - Name NVARCHAR(200) NOT NULL, - Columns TEXT, - Filter TEXT, - LastUpdated DATETIME NULL, - NextUpdate DATETIME NULL, - UpdateDelay INT DEFAULT 0, - QueryTableName NVARCHAR(200) NULL, - QueryTableContainer ENTITYID, - ParticipantGroups TEXT, - - CONSTRAINT PK_RowId PRIMARY KEY (RowId), - CONSTRAINT FK_QuerySnapshotDef_QueryDefId FOREIGN KEY (QueryDefId) REFERENCES query.QueryDef (QueryDefId) -); - -ALTER TABLE query.QuerySnapshotDef ADD OptionsId INT NULL; - -CREATE TABLE query.OlapDef -( - RowId INT IDENTITY(1, 1) NOT NULL, - Created DATETIME NULL, - CreatedBy INT NULL, - Modified DATETIME NULL, - ModifiedBy INT NULL, - - Container ENTITYID NOT NULL, - Name NVARCHAR(255) NOT NULL, - Module NVARCHAR(255) NOT NULL, - Definition NTEXT NOT NULL, - - CONSTRAINT PK_OlapDef PRIMARY KEY (RowId), - CONSTRAINT UQ_OlapDef UNIQUE (Container, Name) -); diff --git a/query/resources/schemas/dbscripts/sqlserver/query-25.000-25.001.sql b/query/resources/schemas/dbscripts/sqlserver/query-25.000-25.001.sql deleted file mode 100644 index c48fbd366b0..00000000000 --- a/query/resources/schemas/dbscripts/sqlserver/query-25.000-25.001.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- Drop unused column -ALTER TABLE query.QueryDef DROP COLUMN SchemaVersion; diff --git a/query/src/org/labkey/query/controllers/QueryController.java b/query/src/org/labkey/query/controllers/QueryController.java index 383ae131592..8603332e28b 100644 --- a/query/src/org/labkey/query/controllers/QueryController.java +++ b/query/src/org/labkey/query/controllers/QueryController.java @@ -8692,12 +8692,9 @@ public Object execute(SqlPromptForm form, BindException errors) throws Exception throw warning.get(); } // if that worked, let have the DB check it too - if (ti.getSqlDialect().isPostgreSQL()) - { - // CONSIDER: will this work with LabKey SQL named parameters? - SQLFragment sql = new SQLFragment("PREPARE validate AS SELECT * FROM ").append(ti.getFromSQL("MYVALIDATEQUERY__")); - new SqlExecutor(ti.getSchema().getScope()).execute(sql); - } + // CONSIDER: will this work with LabKey SQL named parameters? + SQLFragment sql = new SQLFragment("PREPARE validate AS SELECT * FROM ").append(ti.getFromSQL("MYVALIDATEQUERY__")); + new SqlExecutor(ti.getSchema().getScope()).execute(sql); } catch (Exception x) { diff --git a/query/src/org/labkey/query/controllers/SqlController.java b/query/src/org/labkey/query/controllers/SqlController.java index 7e9f28e9fb9..8f556da7034 100644 --- a/query/src/org/labkey/query/controllers/SqlController.java +++ b/query/src/org/labkey/query/controllers/SqlController.java @@ -34,7 +34,6 @@ import org.labkey.api.data.ColumnInfo; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerManager; -import org.labkey.api.data.CoreSchema; import org.labkey.api.data.DisplayColumn; import org.labkey.api.data.JdbcType; import org.labkey.api.data.PropertyStorageSpec; @@ -622,15 +621,12 @@ public void setUp() throws Exception list.getDomain().addProperty(new PropertyStorageSpec("Age", JdbcType.INTEGER)); list.getDomain().addProperty(new PropertyStorageSpec("Score", JdbcType.DOUBLE)); - if (CoreSchema.getInstance().getSqlDialect().isPostgreSQL()) - { - DomainProperty tagsProp = list.getDomain().addProperty(new PropertyStorageSpec("Tags", JdbcType.VARCHAR)); - tagsProp.setRangeURI(PropertyType.MULTI_CHOICE.getTypeUri()); - IPropertyValidator tcValidator = PropertyService.get().createValidator("urn:lsid:labkey.com:PropertyValidator:textchoice"); - tcValidator.setName("Text Choice Validator"); - tcValidator.setExpressionValue("Red|Green|Blue"); - tagsProp.addValidator(tcValidator); - } + DomainProperty tagsProp = list.getDomain().addProperty(new PropertyStorageSpec("Tags", JdbcType.VARCHAR)); + tagsProp.setRangeURI(PropertyType.MULTI_CHOICE.getTypeUri()); + IPropertyValidator tcValidator = PropertyService.get().createValidator("urn:lsid:labkey.com:PropertyValidator:textchoice"); + tcValidator.setName("Text Choice Validator"); + tcValidator.setExpressionValue("Red|Green|Blue"); + tagsProp.addValidator(tcValidator); list.save(user); @@ -721,12 +717,6 @@ public void testExecute_basic() throws Exception @Test public void testExecute() throws Exception { - if (!CoreSchema.getInstance().getSqlDialect().isPostgreSQL()) - { - testExecute_basic(); - return; - } - MockHttpServletResponse response = executeSql("lists", "SELECT Name, Age, Score, Tags FROM " + LIST_NAME + " ORDER BY Name", Format.split); assertEquals(HttpServletResponse.SC_OK, response.getStatus()); diff --git a/query/src/org/labkey/query/persist/QueryManager.java b/query/src/org/labkey/query/persist/QueryManager.java index 30b0df1af29..0c11951341c 100644 --- a/query/src/org/labkey/query/persist/QueryManager.java +++ b/query/src/org/labkey/query/persist/QueryManager.java @@ -1089,8 +1089,6 @@ private static Map getExportTypeCountsMetric() if (schema != null) { DbSchema dbSchema = schema.getDbSchema(); - if (!dbSchema.getSqlDialect().isPostgreSQL()) - return null; // deliberately not reporting metrics from SQL Server TableInfo table = schema.getTable(QueryExportAuditProvider.QUERY_AUDIT_EVENT, new ContainerFilter.AllFolders(adminUser)); if (table != null) { diff --git a/search/module.properties b/search/module.properties index 120e6d9f57a..aa7a6927b5f 100644 --- a/search/module.properties +++ b/search/module.properties @@ -7,5 +7,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/search/resources/schemas/dbscripts/sqlserver/search-0.000-25.000.sql b/search/resources/schemas/dbscripts/sqlserver/search-0.000-25.000.sql deleted file mode 100644 index 712d6276c53..00000000000 --- a/search/resources/schemas/dbscripts/sqlserver/search-0.000-25.000.sql +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2015-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE SCHEMA search; -GO - -CREATE TABLE search.CrawlCollections -( - id INT IDENTITY(1,1), - - Parent INT, - Name NVARCHAR(448) NOT NULL, - Path NVARCHAR(2000) NOT NULL, - csPath AS CHECKSUM(Path), - - Modified DATETIME NULL, - LastCrawled DATETIME NULL, - ChangeInterval INT NULL DEFAULT 1000*60*60*24, - NextCrawl DATETIME NOT NULL DEFAULT CAST('1967-10-04' as DATETIME), - - -- NOTE: Path is too long to use for primary key - CONSTRAINT PK_Collections PRIMARY KEY (id), - CONSTRAINT AK_Unique UNIQUE (Parent, Name) -); -CREATE INDEX IDX_PathHash ON search.CrawlCollections(csPath); -CREATE INDEX IDX_NextCrawl ON search.CrawlCollections(NextCrawl); - -CREATE TABLE search.CrawlResources -( - Parent INT, - Name NVARCHAR(448) NOT NULL, - - Modified DATETIME NULL, -- filesystem time - LastIndexed DATETIME NULL, -- server time - CONSTRAINT PK_Resources PRIMARY KEY (Parent,Name) -); diff --git a/search/resources/schemas/dbscripts/sqlserver/search-26.000-26.001.sql b/search/resources/schemas/dbscripts/sqlserver/search-26.000-26.001.sql deleted file mode 100644 index 4c655d4ab98..00000000000 --- a/search/resources/schemas/dbscripts/sqlserver/search-26.000-26.001.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- Upgrade Lucene to 10.3.2 -EXEC core.executeJavaUpgradeCode 'reindex'; diff --git a/search/src/org/labkey/search/SearchModule.java b/search/src/org/labkey/search/SearchModule.java index ace08e996e4..69e652a08a1 100644 --- a/search/src/org/labkey/search/SearchModule.java +++ b/search/src/org/labkey/search/SearchModule.java @@ -23,7 +23,6 @@ import org.labkey.api.cache.CacheManager; import org.labkey.api.data.ContainerFilter; import org.labkey.api.data.ContainerManager; -import org.labkey.api.data.DbSchema; import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; import org.labkey.api.data.UpgradeCode; @@ -100,14 +99,6 @@ public Set getSchemaNames() return PageFlowUtil.set("search"); } - @Override - @NotNull - public Set getSchemasToTest() - { - // Should test the "search" schema, but it differs between SQL Server & PostgreSQL - return Collections.emptySet(); - } - @Override @NotNull protected Collection createWebPartFactories() diff --git a/search/src/org/labkey/search/model/SavePaths.java b/search/src/org/labkey/search/model/SavePaths.java index 40ef93a7e8f..b7dff7716e7 100644 --- a/search/src/org/labkey/search/model/SavePaths.java +++ b/search/src/org/labkey/search/model/SavePaths.java @@ -82,12 +82,8 @@ private boolean _update(Path path, @Nullable java.util.Date last, @Nullable java if (null == last) last = nullDate; if (null == next) next = oldDate; - DbSchema search = getSearchSchema(); - SqlDialect d = search.getSqlDialect(); - SQLFragment upd = new SQLFragment( - String.format("UPDATE search.CrawlCollections %s SET LastCrawled=?, NextCrawl=? ", - d.isSqlServer() ? "WITH (UPDLOCK)" : ""), + "UPDATE search.CrawlCollections SET LastCrawled=?, NextCrawl=? ", last, next); upd.append(" WHERE " ); SQLFragment f = pathFilter(getSearchSchema().getTable("CrawlCollections"), pathStr); @@ -382,9 +378,7 @@ public Map> getPaths(int limit) // UPDATE LastCrawled so we won't try to crawl for a while if (!paths.isEmpty()) { - SQLFragment upd = new SQLFragment( - "UPDATE search.CrawlCollections " + (getSearchSchema().getSqlDialect().isSqlServer() ? " WITH (UPDLOCK)" : "") + "\n" + - "SET LastCrawled=?", now); + SQLFragment upd = new SQLFragment("UPDATE search.CrawlCollections\nSET LastCrawled=?", now); upd.append(updWHERE); new SqlExecutor(getSearchSchema()).execute(upd); } diff --git a/specimen/module.properties b/specimen/module.properties index 465594d3139..b069d0b2f2e 100644 --- a/specimen/module.properties +++ b/specimen/module.properties @@ -5,5 +5,4 @@ Description: A system for tracking specimens as part of a study. \ URL: https://www.labkey.com/products-services/sample-management-software/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/specimen/src/org/labkey/specimen/importer/SpecimenImporter.java b/specimen/src/org/labkey/specimen/importer/SpecimenImporter.java index 41d186ad984..24d0d6fdd1d 100644 --- a/specimen/src/org/labkey/specimen/importer/SpecimenImporter.java +++ b/specimen/src/org/labkey/specimen/importer/SpecimenImporter.java @@ -485,25 +485,14 @@ private void populateSpecimenTables(SpecimenLoadInfo info, boolean merge) throws { // SimpleFilter containerFilter = SimpleFilter.createContainerFilter(info.getContainer()); info("Deleting old data from SpecimenEvent, Vial and Specimen tables..."); - if (getTableInfoSpecimen().getSchema().getSqlDialect().isPostgreSQL()) - { - SQLFragment sql = new SQLFragment("TRUNCATE ") - .append(getTableInfoSpecimenEvent().getSelectName()) - .append(", ") - .append(getTableInfoVial().getSelectName()) - .append(", ") - .append(getTableInfoSpecimen().getSelectName()); + SQLFragment sql = new SQLFragment("TRUNCATE ") + .append(getTableInfoSpecimenEvent().getSelectName()) + .append(", ") + .append(getTableInfoVial().getSelectName()) + .append(", ") + .append(getTableInfoSpecimen().getSelectName()); - executeSQL(getTableInfoSpecimen().getSchema(), sql); - } - else - { - Table.delete(getTableInfoSpecimenEvent()); - ensureNotCanceled(); - Table.delete(getTableInfoVial()); - ensureNotCanceled(); - Table.delete(getTableInfoSpecimen()); - } + executeSQL(getTableInfoSpecimen().getSchema(), sql); info("Complete."); } diff --git a/study/module.properties b/study/module.properties index daf6cc26d53..3efcf302635 100644 --- a/study/module.properties +++ b/study/module.properties @@ -7,5 +7,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/study/resources/schemas/dbscripts/sqlserver/study-0.000-24.000.sql b/study/resources/schemas/dbscripts/sqlserver/study-0.000-24.000.sql deleted file mode 100644 index fee69737767..00000000000 --- a/study/resources/schemas/dbscripts/sqlserver/study-0.000-24.000.sql +++ /dev/null @@ -1,1013 +0,0 @@ --- noinspection SqlResolveForFile - --- noinspection SqlResolveForFile @ object-type/"USERID" --- noinspection SqlResolveForFile @ object-type/"ENTITYID" - -/* - * Copyright (c) 2019-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -CREATE SCHEMA study; -GO -CREATE SCHEMA studyDataset; -GO -CREATE SCHEMA specimenTables; -GO -CREATE SCHEMA studydesign; -GO - -CREATE TABLE study.Study -( - Label NVARCHAR(200) NULL, - Container ENTITYID NOT NULL, - EntityId ENTITYID, - TimepointType NVARCHAR(15) NOT NULL, - StartDate DATETIME, - ParticipantCohortDataSetId INT NULL, - ParticipantCohortProperty NVARCHAR(200) NULL, - SecurityType NVARCHAR(32) NOT NULL, - LSID NVARCHAR(200) NOT NULL, - ManualCohortAssignment BIT NOT NULL DEFAULT 0, - DefaultPipelineQCState INT, - DefaultAssayQCState INT, - DefaultDirectEntryQCState INT, - ShowPrivateDataByDefault BIT NOT NULL DEFAULT 0, - AllowReload BIT NOT NULL DEFAULT 0, - ReloadInterval INT NULL, - LastReload DATETIME NULL, - ReloadUser UserId, - AdvancedCohorts BIT NOT NULL DEFAULT 0, - ParticipantCommentDataSetId INT NULL, - ParticipantCommentProperty NVARCHAR(200) NULL, - ParticipantVisitCommentDataSetId INT NULL, - ParticipantVisitCommentProperty NVARCHAR(200) NULL, - SubjectNounSingular NVARCHAR(50) NOT NULL DEFAULT 'Participant', - SubjectNounPlural NVARCHAR(50) NOT NULL DEFAULT 'Participants', - SubjectColumnName NVARCHAR(50) NOT NULL DEFAULT 'ParticipantId', - - CONSTRAINT PK_Study PRIMARY KEY (Container) -); - -ALTER TABLE study.Study ADD CONSTRAINT FK_Study_DefaultPipelineQCState FOREIGN KEY (DefaultPipelineQCState) REFERENCES core.DataStates (RowId); -ALTER TABLE study.Study ADD CONSTRAINT FK_Study_DefaultDirectEntryQCState FOREIGN KEY (DefaultDirectEntryQCState) REFERENCES core.DataStates (RowId); -ALTER TABLE study.Study ADD CONSTRAINT FK_Study_DefaultAssayQCState FOREIGN KEY (DefaultAssayQCState) REFERENCES core.DataStates (RowId); - -ALTER TABLE study.Study ADD BlankQCStatePublic BIT NOT NULL DEFAULT 0 -GO - -ALTER TABLE study.Study ADD Description text -ALTER TABLE study.Study ADD ProtocolDocumentEntityId ENTITYID -ALTER TABLE study.Study ALTER COLUMN ProtocolDocumentEntityId ENTITYID NOT NULL -ALTER TABLE study.Study ADD SourceStudyContainerId ENTITYID -ALTER TABLE study.Study ADD DescriptionRendererType VARCHAR(50) NOT NULL DEFAULT 'TEXT_WITH_LINKS'; -ALTER TABLE study.Study ADD investigator nvarchar(200) -ALTER TABLE study.Study ADD studyGrant nvarchar(200) - -EXEC sp_RENAME 'study.Study.studyGrant', 'Grant', 'COLUMN'; - -ALTER TABLE study.study ADD DefaultTimepointDuration INT NOT NULL DEFAULT 1; - -DELETE FROM study.study WHERE Container NOT IN (SELECT EntityId FROM core.Containers); - -ALTER TABLE study.Study - ADD CONSTRAINT FK_Study_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId); - --- Add columns to store an alternate ID "template", i.e., an optional prefix and number of digits to use when generating random alternate IDs -ALTER TABLE study.Study ADD AlternateIdPrefix VARCHAR(20) NULL; -ALTER TABLE study.Study ADD AlternateIdDigits INT NOT NULL DEFAULT 6; - -ALTER TABLE study.Study ADD - StudySnapshot INT NULL, - LastSpecimenLoad DATETIME NULL; -- Helps determine whether a specimen refresh is needed - -CREATE INDEX IX_Study_StudySnapshot ON study.Study(StudySnapshot); - -ALTER TABLE study.Study ADD AllowReqLocRepository BIT NOT NULL DEFAULT 1; -ALTER TABLE study.Study ADD AllowReqLocClinic BIT NOT NULL DEFAULT 1; -ALTER TABLE study.Study ADD AllowReqLocSAL BIT NOT NULL DEFAULT 1; -ALTER TABLE study.Study ADD AllowReqLocEndpoint BIT NOT NULL DEFAULT 1; -ALTER TABLE study.study ADD ParticipantAliasDatasetName NVARCHAR(200); -ALTER TABLE study.study ADD ParticipantAliasSourceColumnName NVARCHAR(200); -ALTER TABLE study.study ADD ParticipantAliasColumnName NVARCHAR(200); -ALTER TABLE study.study DROP COLUMN ParticipantAliasDatasetName; -ALTER TABLE study.study ADD ParticipantAliasDatasetId INT; - -EXEC sp_rename 'study.study.ParticipantAliasSourceColumnName', 'ParticipantAliasSourceProperty', 'COLUMN'; -EXEC sp_rename 'study.study.ParticipantAliasColumnName', 'ParticipantAliasProperty', 'COLUMN'; - --- new fields to add to existing study properties table -ALTER TABLE study.Study ADD Species NVARCHAR(200); -ALTER TABLE study.Study ADD EndDate DATETIME; -ALTER TABLE study.Study ADD AssayPlan NTEXT; - -ALTER TABLE study.Study ALTER COLUMN Description NVARCHAR(MAX); - -ALTER TABLE study.Study ADD ShareDatasetDefinitions BIT NOT NULL DEFAULT 0; - --- Add new skip query validation column to study.study -ALTER TABLE study.Study ADD ValidateQueriesAfterImport BIT NOT NULL DEFAULT 0; -GO - -ALTER TABLE study.Study ADD ShareVisitDefinitions BIT NOT NULL DEFAULT 0; - -/* 21.xxx SQL scripts */ - -EXEC sp_rename 'study.Study.DefaultAssayQCState', 'DefaultPublishDataQCState', 'COLUMN'; - -/* 22.xxx SQL scripts */ - -EXEC core.fn_dropifexists 'Study', 'study', 'DEFAULT', 'AllowReload'; - -ALTER TABLE study.study DROP COLUMN AllowReload; -ALTER TABLE study.study DROP COLUMN LastReload; -ALTER TABLE study.study DROP COLUMN ReloadInterval; -ALTER TABLE study.study DROP COLUMN ReloadUser; -CREATE TABLE study.Cohort -( - RowId INT IDENTITY(1,1), - Label NVARCHAR(200) NULL, - Container ENTITYID NOT NULL, - LSID NVARCHAR(200) NOT NULL, - - CONSTRAINT PK_Cohort PRIMARY KEY (RowId), - CONSTRAINT UQ_Cohort_Label UNIQUE(Label, Container) -); - -ALTER TABLE study.Cohort ADD Enrolled BIT NOT NULL DEFAULT 1; - --- new fields to add to existing cohort table -ALTER TABLE study.Cohort ADD SubjectCount INT; -ALTER TABLE study.Cohort ADD Description NTEXT; - -CREATE TABLE study.Visit -( - RowId INT IDENTITY(1,1) NOT NULL, - SequenceNumMin NUMERIC(15,4) NOT NULL DEFAULT 0, - SequenceNumMax NUMERIC(15,4) NOT NULL DEFAULT 0, - Label NVARCHAR(200) NULL, - TypeCode CHAR(1) NULL, - ShowByDefault BIT NOT NULL DEFAULT 1, - DisplayOrder INT NOT NULL DEFAULT 0, - Container ENTITYID NOT NULL, - VisitDateDatasetId INT, - CohortId INT NULL, - ChronologicalOrder INTEGER NOT NULL DEFAULT 0, - - CONSTRAINT PK_Visit PRIMARY KEY (Container, RowId), - CONSTRAINT UQ_Visit_ContSeqNum UNIQUE (Container, SequenceNumMin), - CONSTRAINT FK_Visit_Cohort FOREIGN KEY (CohortId) REFERENCES study.Cohort (RowId) -); - -CREATE INDEX IX_Visit_CohortId ON study.Visit(CohortId); - -ALTER TABLE study.Visit ADD SequenceNumHandling VARCHAR(32) NULL; -ALTER TABLE study.Visit ADD Description NTEXT; -GO - --- new fields to add to existing visit table, default SequenceNumTarget to SequenceNumMin -ALTER TABLE study.Visit ADD SequenceNumTarget NUMERIC(15,4) NOT NULL DEFAULT 0; - -EXEC sp_rename 'study.visit.SequenceNumTarget', 'ProtocolDay', 'COLUMN'; -GO - -UPDATE study.Visit -SET ProtocolDay = Round((SequenceNumMax + SequenceNumMin)/2, 0) -FROM study.Study SS -WHERE SS.Container = study.Visit.Container AND SS.TimePointType = 'DATE'; - ---ALTER TABLE study.visit ALTER protocolday DROP NOT NULL; -EXEC core.fn_dropifexists 'Visit', 'study', 'DEFAULT', 'ProtocolDay'; -GO -ALTER TABLE study.Visit ALTER COLUMN ProtocolDay NUMERIC(15,4) NULL; -GO -ALTER TABLE study.Visit ADD DEFAULT NULL FOR ProtocolDay; - -CREATE TABLE study.VisitMap -( - Container ENTITYID NOT NULL, - VisitRowId INT NOT NULL DEFAULT -1, - DataSetId INT NOT NULL, -- FK - Required BIT NOT NULL DEFAULT 1, - - CONSTRAINT PK_VisitMap PRIMARY KEY (Container,VisitRowId,DataSetId) -); - -CREATE TABLE study.DataSet -- AKA CRF or Assay -( - Container ENTITYID NOT NULL, - DataSetId INT NOT NULL, - TypeURI NVARCHAR(200) NULL, - Label NVARCHAR(200) NOT NULL, - ShowByDefault BIT NOT NULL DEFAULT 1, - DisplayOrder INT NOT NULL DEFAULT 0, - Category NVARCHAR(200) NULL, - EntityId ENTITYID, - VisitDatePropertyName NVARCHAR(200), - KeyPropertyName NVARCHAR(50) NULL, -- Property name in TypeURI - Name VARCHAR(200) NOT NULL, - Description NTEXT NULL, - DemographicData BIT DEFAULT 0, - CohortId INT NULL, - ProtocolId INT NULL, - KeyManagementType VARCHAR(10) NOT NULL, - - CONSTRAINT PK_DataSet PRIMARY KEY CLUSTERED (Container, DataSetId), - CONSTRAINT UQ_DatasetName UNIQUE (Container, Name), - CONSTRAINT UQ_DatasetLabel UNIQUE (Container, Label), - CONSTRAINT FK_Dataset_Cohort FOREIGN KEY (CohortId) REFERENCES study.Cohort (RowId) -); - -CREATE INDEX IX_Dataset_CohortId ON study.Dataset(CohortId); - -ALTER TABLE study.Dataset ADD CategoryId INT; -GO - --- drop the category column -ALTER TABLE study.Dataset DROP COLUMN Category; -ALTER TABLE study.Dataset ADD Modified DATETIME; -ALTER TABLE study.Dataset ADD Type NVARCHAR(50) NOT NULL DEFAULT 'Standard'; - --- clustered indexes just contribute to deadlocks, we don't really need this one - -ALTER TABLE study.DataSet DROP CONSTRAINT PK_DataSet; -GO - -ALTER TABLE study.DataSet ADD CONSTRAINT PK_DataSet PRIMARY KEY (Container, DataSetId); - --- Add new tag column to study.dataset -ALTER TABLE study.dataset ADD Tag VARCHAR(1000); - --- used by shared dataset definitions, specifies if data is shared across folders --- NONE: (default) data is not shared across folders, same as any other container filtered table --- ALL: rows are all shared, visible in all study folders containing this dataset --- PTID: rows are all shared, and are visible if PTID is a found in study.participants for the current folder -ALTER TABLE study.dataset ADD dataSharing NVARCHAR(20) NOT NULL DEFAULT 'NONE'; -ALTER TABLE study.dataset ADD UseTimeKeyField BIT NOT NULL DEFAULT 0; -ALTER TABLE study.Dataset ALTER COLUMN TypeURI NVARCHAR(300); - -EXEC sp_rename 'study.Dataset.ProtocolId', 'PublishSourceId', 'COLUMN'; - -ALTER TABLE study.Dataset ADD PublishSourceType NVARCHAR(50); -GO -UPDATE study.Dataset SET PublishSourceType = 'Assay' - WHERE PublishSourceId IS NOT NULL; - --- ParticipantId is not a sequence, we assume these are externally defined -CREATE TABLE study.Participant -( - Container ENTITYID NOT NULL, - ParticipantId NVARCHAR(32) NOT NULL, - EnrollmentSiteId INT NULL, - CurrentSiteId INT NULL, - StartDate DATETIME, - CurrentCohortId INT NULL, - InitialCohortId INTEGER, - - CONSTRAINT PK_Participant PRIMARY KEY (Container, ParticipantId) -); - -CREATE INDEX IX_Participant_ParticipantId ON study.Participant(ParticipantId); -CREATE INDEX IX_Participant_InitialCohort ON study.Participant(InitialCohortId); - --- TODO: These indexes are redundant... but the old create index, rename column, create index steps left us in this state -CREATE INDEX IX_Participant_CohortId ON study.Participant(CurrentCohortId); -CREATE INDEX IX_Participant_CurrentCohort ON study.Participant(CurrentCohortId); - --- Default to random offset, 1 - 365 -ALTER TABLE study.Participant ADD DateOffset INT NOT NULL DEFAULT ABS(CHECKSUM(NEWID())) % 364 + 1; - --- Random alternate IDs are set via code -ALTER TABLE study.Participant ADD AlternateId VARCHAR(32) NULL; - --- Track participant indexing in the participant table now -ALTER TABLE study.Participant ADD LastIndexed DATETIME NULL; - --- Add Modified column so we can actually use LastIndexed, #31139 -ALTER TABLE study.Participant ADD Modified DATETIME; -GO - -UPDATE study.Participant SET Modified = CURRENT_TIMESTAMP; - -CREATE TABLE study.SampleRequestStatus -( - RowId INT IDENTITY(1,1), - Container ENTITYID NOT NULL, - SortOrder INT NULL, - Label NVARCHAR(100), - FinalState BIT NOT NULL DEFAULT 0, - SpecimensLocked BIT NOT NULL DEFAULT 1, - - CONSTRAINT PK_SampleRequestStatus PRIMARY KEY (RowId) -); - -CREATE INDEX IX_SampleRequestStatus_Container ON study.SampleRequestStatus(Container); - -CREATE TABLE study.SampleRequestActor -( - RowId INT IDENTITY(1,1), - Container ENTITYID NOT NULL, - SortOrder INT NULL, - Label NVARCHAR(100), - PerSite Bit NOT NULL DEFAULT 0, - - CONSTRAINT PK_SampleRequestActor PRIMARY KEY (RowId) -); - -CREATE INDEX IX_SampleRequestActor_Container ON study.SampleRequestActor(Container); - -CREATE TABLE study.SampleRequest -( - -- standard fields - _ts TIMESTAMP, - RowId INT IDENTITY(1,1), - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - StatusId INT NOT NULL, - Comments NTEXT, - DestinationSiteId INT NULL, - Hidden Bit NOT NULL DEFAULT 0, - EntityId ENTITYID NULL, - - CONSTRAINT PK_SampleRequest PRIMARY KEY (RowId), - CONSTRAINT FK_SampleRequest_SampleRequestStatus FOREIGN KEY (StatusId) REFERENCES study.SampleRequestStatus(RowId) -); - -CREATE INDEX IX_SampleRequest_Container ON study.SampleRequest(Container); -CREATE INDEX IX_SampleRequest_StatusId ON study.SampleRequest(StatusId); -CREATE INDEX IX_SampleRequest_DestinationSiteId ON study.SampleRequest(DestinationSiteId); -CREATE INDEX IX_SampleRequest_EntityId ON study.SampleRequest(EntityId); - -CREATE TABLE study.SampleRequestRequirement -( - RowId INT IDENTITY(1,1), - Container ENTITYID NOT NULL, - RequestId INT NOT NULL, - ActorId INT NOT NULL, - SiteId INT NULL, - Description NVARCHAR(300), - Complete Bit NOT NULL DEFAULT 0, - OwnerEntityId ENTITYID NULL, - - CONSTRAINT PK_SampleRequestRequirement PRIMARY KEY (RowId), - CONSTRAINT FK_SampleRequestRequirement_SampleRequestActor FOREIGN KEY (ActorId) REFERENCES study.SampleRequestActor(RowId) -); - -CREATE INDEX IX_SampleRequestRequirement_Container ON study.SampleRequestRequirement(Container); -CREATE INDEX IX_SampleRequestRequirement_RequestId ON study.SampleRequestRequirement(RequestId); -CREATE INDEX IX_SampleRequestRequirement_ActorId ON study.SampleRequestRequirement(ActorId); -CREATE INDEX IX_SampleRequestRequirement_SiteId ON study.SampleRequestRequirement(SiteId); -CREATE INDEX IX_SampleRequestRequirement_OwnerEntityId ON study.SampleRequestRequirement(OwnerEntityId); - -CREATE TABLE study.SampleRequestEvent -( - RowId INT IDENTITY(1,1) NOT NULL, - EntityId ENTITYID NOT NULL, - CreatedBy USERID, - Created DATETIME, - Container ENTITYID NOT NULL, - RequestId INT NOT NULL, - Comments NTEXT, - EntryType NVARCHAR(64), - RequirementId INT NULL, - - CONSTRAINT PK_SampleRequestEvent PRIMARY KEY (RowId), - CONSTRAINT FK_SampleRequestEvent_SampleRequest FOREIGN KEY (RequestId) REFERENCES study.SampleRequest(RowId) -); - -CREATE INDEX IX_SampleRequestEvent_Container ON study.SampleRequestEvent(Container); -CREATE INDEX IX_SampleRequestEvent_RequestId ON study.SampleRequestEvent(RequestId); - -CREATE TABLE study.SampleRequestSpecimen -( - RowId INT IDENTITY(1, 1), - Container ENTITYID NOT NULL, - SampleRequestId INT NOT NULL, - SpecimenGlobalUniqueId NVARCHAR(100), - Orphaned BIT NOT NULL DEFAULT 0, - - CONSTRAINT PK_SampleRequestSpecimen PRIMARY KEY (RowId), - CONSTRAINT FK_SampleRequestSpecimen_SampleRequest FOREIGN KEY (SampleRequestId) REFERENCES study.SampleRequest(RowId) -); - -CREATE INDEX IX_SampleRequestSpecimen_Container ON study.SampleRequestSpecimen(Container); -CREATE INDEX IX_SampleRequestSpecimen_SampleRequestId ON study.SampleRequestSpecimen(SampleRequestId); -CREATE INDEX IX_SampleRequestSpecimen_SpecimenGlobalUniqueId ON study.SampleRequestSpecimen(SpecimenGlobalUniqueId); - -CREATE TABLE study.UploadLog -( - RowId INT IDENTITY NOT NULL, - Container ENTITYID NOT NULL, - Created DATETIME NOT NULL, - CreatedBy USERID NOT NULL, - Description TEXT, - FilePath NVARCHAR(400), -- Stay under SQL Server's maximum key length of 900 bytes - DatasetId INT NOT NULL, - Status NVARCHAR(20), - - CONSTRAINT PK_UploadLog PRIMARY KEY (RowId), - CONSTRAINT UQ_UploadLog_FilePath UNIQUE (FilePath) -); - -CREATE TABLE study.ParticipantVisit -( - Container ENTITYID NOT NULL, - ParticipantId NVARCHAR(32) NOT NULL, - VisitRowId INT NULL, - SequenceNum NUMERIC(15,4) NOT NULL, - VisitDate DATETIME NULL, - Day INTEGER, - CohortID INT NULL, - ParticipantSequenceKey NVARCHAR(200), - - CONSTRAINT PK_ParticipantVisit PRIMARY KEY (Container, SequenceNum, ParticipantId), - CONSTRAINT FK_ParticipantVisit_Cohort FOREIGN KEY (CohortID) REFERENCES study.Cohort (RowId), - CONSTRAINT UQ_StudyData_ParticipantSequenceKey UNIQUE (ParticipantSequenceKey, Container) -); - -CREATE INDEX IX_ParticipantVisit_Container ON study.ParticipantVisit(Container); -CREATE INDEX IX_ParticipantVisit_ParticipantId ON study.ParticipantVisit(ParticipantId); -CREATE INDEX IX_ParticipantVisit_SequenceNum ON study.ParticipantVisit(SequenceNum); -CREATE INDEX IX_ParticipantVisit_ParticipantSequenceKey ON study.ParticipantVisit(ParticipantSequenceKey, Container); - --- Rename 'ParticipantSequenceKey' to 'ParticipantSequenceNum' along with constraints and indices. -EXEC sp_rename 'study.ParticipantVisit.ParticipantSequenceKey', 'ParticipantSequenceNum', 'COLUMN'; -EXEC sp_rename 'study.ParticipantVisit.UQ_StudyData_ParticipantSequenceKey', 'UQ_ParticipantVisit_ParticipantSequenceNum'; -EXEC sp_rename 'study.ParticipantVisit.IX_ParticipantVisit_ParticipantSequenceKey', 'IX_ParticipantVisit_ParticipantSequenceNum', 'INDEX'; -GO - --- To change the PK, it is more efficient to drop all other indexes (including unique constraints), --- drop and recreate PK, and then rebuild indexes - -ALTER TABLE study.ParticipantVisit DROP CONSTRAINT UQ_ParticipantVisit_ParticipantSequenceNum; - --- changing order of keys to make supporting index useful for Container+Participant queries -ALTER TABLE study.ParticipantVisit DROP CONSTRAINT PK_ParticipantVisit; - --- Consider: do we need a unique constraint on ParticipantSequenceNum if we have separate ones on Participant, SequenceNum ?? -DROP INDEX study.ParticipantVisit.IX_ParticipantVisit_Container; -DROP INDEX study.ParticipantVisit.IX_ParticipantVisit_ParticipantId; -DROP INDEX study.ParticipantVisit.IX_ParticipantVisit_ParticipantSequenceNum; -DROP INDEX study.ParticipantVisit.IX_ParticipantVisit_SequenceNum; - --- Was previously Container, SequenceNum, ParticipantId -ALTER TABLE study.ParticipantVisit ADD CONSTRAINT PK_ParticipantVisit PRIMARY KEY CLUSTERED - (Container, ParticipantId, SequenceNum); - - -ALTER TABLE study.ParticipantVisit ADD CONSTRAINT UQ_ParticipantVisit_ParticipantSequenceNum UNIQUE -(ParticipantSequenceNum ASC, Container ASC); - -CREATE INDEX IX_ParticipantVisit_ParticipantId ON study.ParticipantVisit (ParticipantId); -CREATE INDEX IX_ParticipantVisit_SequenceNum ON study.ParticipantVisit (SequenceNum); - --- clean up some bad participantsequencenum values seen in the wild -DELETE FROM Study.ParticipantVisit WHERE ParticipantSequenceNum = 'NULL'; - -UPDATE study.participantvisit SET visitrowid=-1 WHERE visitrowid IS NULL; -ALTER TABLE study.participantvisit ALTER COLUMN visitrowid INT NOT NULL; -ALTER TABLE study.participantvisit ADD CONSTRAINT study_pv_visitrowid_def DEFAULT -1 for visitrowid; - -EXEC core.fn_dropifexists 'ParticipantVisit', 'study', 'INDEX', 'IX_PV_SequenceNum'; -EXEC core.fn_dropifexists 'ParticipantVisit', 'study', 'INDEX', 'IX_ParticipantVisit_ParticipantId'; -EXEC core.fn_dropifexists 'ParticipantVisit', 'study', 'INDEX', 'IX_ParticipantVisit_SequenceNum'; - -CREATE INDEX IX_PV_SequenceNum ON study.ParticipantVisit (Container, SequenceNum) INCLUDE (VisitRowId); - -EXEC core.fn_dropifexists 'ParticipantVisit', 'study', 'INDEX', 'IX_PV_SequenceNum'; -EXEC core.fn_dropifexists 'ParticipantVisit', 'study', 'INDEX', 'ix_participantvisit_sequencenum'; -EXEC core.fn_dropifexists 'ParticipantVisit', 'study', 'INDEX', 'ix_participantvisit_visitrowid'; - --- For Resync perf -CREATE INDEX ix_participantvisit_sequencenum ON study.participantvisit (container, participantid, sequencenum, ParticipantSequenceNum); - --- Adding as an explicit index because it got lost on postgresql as an include column -CREATE INDEX ix_participantvisit_visitrowid ON study.participantvisit (visitrowid); - -CREATE TABLE study.StudyDesign -( - -- standard fields - _ts TIMESTAMP, - StudyId INT IDENTITY(1,1), - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - PublicRevision INT NULL, - DraftRevision INT NULL, - Label NVARCHAR(200) NOT NULL, - Active BIT DEFAULT 0, - SourceContainer ENTITYID, - - CONSTRAINT PK_StudyDesign PRIMARY KEY (StudyId), - CONSTRAINT UQ_StudyDesign UNIQUE (Container,StudyId), - CONSTRAINT UQ_StudyDesignLabel UNIQUE (Container, Label) -); - -CREATE TABLE study.StudyDesignVersion -( - -- standard fields - _ts TIMESTAMP, - RowId INT IDENTITY(1,1), - StudyId INT NOT NULL, - CreatedBy USERID, - Created DATETIME, - Container ENTITYID NOT NULL, - Revision INT NOT NULL, - Draft Bit NOT NULL DEFAULT 1, - Label NVARCHAR(200) NOT NULL, - Description NTEXT, - XML NTEXT, - - CONSTRAINT PK_StudyDesignVersion PRIMARY KEY (StudyId,Revision), - CONSTRAINT FK_StudyDesignVersion_StudyDesign FOREIGN KEY (StudyId) REFERENCES study.StudyDesign(StudyId), - CONSTRAINT UQ_StudyDesignVersion UNIQUE (Container,Label,Revision) -); - -CREATE TABLE study.ParticipantView -( - RowId INT IDENTITY(1,1), - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - Body TEXT, - Active BIT NOT NULL, - - CONSTRAINT PK_ParticipantView PRIMARY KEY (RowId), - CONSTRAINT FK_ParticipantView_Container FOREIGN KEY (Container) REFERENCES core.Containers (EntityId) -); - -CREATE TABLE study.SpecimenComment -( - RowId INT IDENTITY(1,1), - Container ENTITYID NOT NULL, - GlobalUniqueId NVARCHAR(50) NOT NULL, - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Comment NTEXT, - SpecimenHash NVARCHAR(256), - QualityControlFlag BIT NOT NULL DEFAULT 0, - QualityControlFlagForced BIT NOT NULL DEFAULT 0, - QualityControlComments NVARCHAR(512), - - CONSTRAINT PK_SpecimenComment PRIMARY KEY (RowId) -); - -CREATE INDEX IX_SpecimenComment_GlobalUniqueId ON study.SpecimenComment(GlobalUniqueId); -CREATE INDEX IX_SpecimenComment_SpecimenHash ON study.SpecimenComment(Container, SpecimenHash); - -CREATE TABLE study.SampleAvailabilityRule -( - RowId INT IDENTITY(1,1), - Container EntityId NOT NULL, - SortOrder INTEGER NOT NULL, - RuleType NVARCHAR(50), - RuleData NVARCHAR(250), - MarkType NVARCHAR(30), - - CONSTRAINT PL_SampleAvailabilityRule PRIMARY KEY (RowId) -); - -CREATE TABLE study.VisitAliases -( - RowId INT IDENTITY(1,1) NOT NULL, - Container ENTITYID NOT NULL, - Name NVARCHAR(200) NOT NULL, - SequenceNum NUMERIC(15, 4) NOT NULL, - - CONSTRAINT PK_VisitNames PRIMARY KEY (RowId) -); - -CREATE UNIQUE INDEX UQ_VisitAliases_Name ON study.VisitAliases (Container, Name); - --- named sets of normalization factors -CREATE TABLE study.ParticipantCategory -( - RowId INT IDENTITY(1,1) NOT NULL, - EntityId ENTITYID NOT NULL, - CreatedBy USERID, - Created DATETIME, - Container ENTITYID NOT NULL, - - Label NVARCHAR(200) NOT NULL, - Type NVARCHAR(60) NOT NULL, - Shared BIT, - AutoUpdate BIT, - - -- for queries - QueryName NVARCHAR(200), - ViewName NVARCHAR(200), - SchemaName NVARCHAR(50), - - -- for cohorts - DatasetId INT, - GroupProperty NVARCHAR(200), - - CONSTRAINT pk_participantCategory PRIMARY KEY (RowId), - CONSTRAINT uq_Label_Container UNIQUE (Label, Container) -) -GO - --- named sets of normalization factors -ALTER TABLE study.ParticipantCategory ADD ModifiedBy USERID -GO -ALTER TABLE study.ParticipantCategory ADD Modified DATETIME -GO - --- Create an owner column to represent shared or private participant categories -ALTER TABLE study.ParticipantCategory ADD OwnerId USERID NOT NULL DEFAULT -1; -GO - -ALTER TABLE study.ParticipantCategory DROP CONSTRAINT uq_label_container; -ALTER TABLE study.ParticipantCategory DROP COLUMN Shared; -ALTER TABLE study.ParticipantCategory ADD CONSTRAINT uq_label_container_owner UNIQUE(Label, Container, OwnerId); -GO - --- represents a grouping category for a participant category -CREATE TABLE study.ParticipantGroup -( - RowId INT IDENTITY(1,1) NOT NULL, - Container ENTITYID NOT NULL, - - Label NVARCHAR(200) NOT NULL, - CategoryId INT NOT NULL, - - CONSTRAINT pk_participantGroup PRIMARY KEY (RowId) -) -GO - --- Add Foreign Key constraint -ALTER TABLE study.ParticipantGroup - ADD CONSTRAINT fk_participantCategory_categoryId FOREIGN KEY (CategoryId) REFERENCES study.ParticipantCategory (RowId) -GO - -ALTER TABLE study.ParticipantGroup ADD - Filter NTEXT NULL, - Description NVARCHAR(250) NULL -GO - -EXEC sp_RENAME 'study.ParticipantGroup.Filter', 'Filters', 'COLUMN'; - -ALTER TABLE study.ParticipantGroup ADD CreatedBy USERID; -ALTER TABLE study.ParticipantGroup ADD Created DATETIME; -ALTER TABLE study.ParticipantGroup ADD ModifiedBy USERID; -ALTER TABLE study.ParticipantGroup ADD Modified DATETIME; -GO - --- maps participants to participant groups -CREATE TABLE study.ParticipantGroupMap -( - GroupId INT NOT NULL, - ParticipantId NVARCHAR(32) NOT NULL, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_participantGroupMap PRIMARY KEY (GroupId, ParticipantId, Container), - CONSTRAINT fk_participantGroup_groupId FOREIGN KEY (GroupId) REFERENCES study.ParticipantGroup (RowId), - CONSTRAINT fk_participant_participantId_container FOREIGN KEY (Container, ParticipantId) REFERENCES study.Participant(Container, ParticipantId) -) -GO - -ALTER TABLE study.ParticipantGroupMap DROP CONSTRAINT fk_participant_participantId_container -GO - -ALTER TABLE study.ParticipantGroupMap ADD CONSTRAINT - fk_participant_participantId_container FOREIGN KEY (Container, ParticipantId) REFERENCES study.Participant(Container, ParticipantId) - ON DELETE CASCADE -GO - --- History of all study snapshots (i.e., ancillary studies and published studies) and the settings used to generate --- them. Rows are effectively owned by both the source and destination container; they remain as long as EITHER the --- source or destination container exists. This table is used primarily to support nightly refresh of specimen data --- (we need to save the protected settings, visit list, and participant list somewhere), but could easily support a --- snapshot history feature. -CREATE TABLE study.StudySnapshot -( - RowId INT IDENTITY(1,1), - Source ENTITYID NULL, -- Source study container; null if this study has been deleted - Destination ENTITYID NULL, -- Destination study container; null if this study has been deleted - CreatedBy USERID, - Created DATETIME, - - Refresh BIT NOT NULL, -- Included in settings, but separate column allows quick filtering - Settings TEXT, - - CONSTRAINT PK_StudySnapshot PRIMARY KEY (RowId) -); - -CREATE INDEX IX_StudySnapshot_Source ON study.StudySnapshot(Source); -CREATE INDEX IX_StudySnapshot_Destination ON study.StudySnapshot(Destination, RowId); - -ALTER TABLE study.StudySnapshot ADD ModifiedBy USERID; -ALTER TABLE study.StudySnapshot ADD Modified DATETIME; -GO - -ALTER TABLE study.StudySnapshot ADD Type VARCHAR(10); -GO - -CREATE TABLE study.StudyDesignImmunogenTypes -( - Name NVARCHAR(200) NOT NULL, - Label NVARCHAR(200) NOT NULL, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesignimmunogentypes PRIMARY KEY (Container, Name) -); - -CREATE TABLE study.StudyDesignGenes -( - Name NVARCHAR(200) NOT NULL, - Label NVARCHAR(200) NOT NULL, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesigngenes PRIMARY KEY (Container, Name) -); - -CREATE TABLE study.StudyDesignRoutes -( - Name NVARCHAR(200) NOT NULL, - Label NVARCHAR(200) NOT NULL, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesignroutes PRIMARY KEY (Container, Name) -); - -CREATE TABLE study.StudyDesignSubTypes -( - Name NVARCHAR(200) NOT NULL, - Label NVARCHAR(200) NOT NULL, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesignsubtypes PRIMARY KEY (Container, Name) -); - -CREATE TABLE study.StudyDesignSampleTypes -( - Name NVARCHAR(200) NOT NULL, - PrimaryType NVARCHAR(200) NOT NULL, - ShortSampleCode NVARCHAR(2) NOT NULL, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesignsampletypes PRIMARY KEY (Container, Name) -); - -CREATE TABLE study.StudyDesignUnits -( - Name NVARCHAR(5) NOT NULL, -- storage name - Label NVARCHAR(200) NOT NULL, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesignunits PRIMARY KEY (Container, Name) -); - -CREATE TABLE study.StudyDesignAssays -( - Name NVARCHAR(200) NOT NULL, - Label NVARCHAR(200) NOT NULL, - Description TEXT, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesignassays PRIMARY KEY (Container, Name) -); - -ALTER TABLE study.StudyDesignAssays ADD Target NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD Methodology NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD Category NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD TargetFunction NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD LeadContributor NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD Contact NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD Summary TEXT; -ALTER TABLE study.StudyDesignAssays ADD Keywords TEXT; -ALTER TABLE study.StudyDesignAssays ADD TargetType NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD TargetSubtype NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD Editorial NVARCHAR(MAX); - -EXEC sp_rename 'study.StudyDesignAssays.Target', 'Type', 'COLUMN'; -GO -EXEC sp_rename 'study.StudyDesignAssays.Methodology', 'Platform', 'COLUMN'; -GO - -ALTER TABLE study.StudyDesignAssays ADD AlternateName NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD Lab NVARCHAR(200); -ALTER TABLE study.StudyDesignAssays ADD LabPI NVARCHAR(200); - -CREATE TABLE study.StudyDesignLabs -( - Name NVARCHAR(200) NOT NULL, - Label NVARCHAR(200) NOT NULL, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesignlabs PRIMARY KEY (Container, Name) -); - -ALTER TABLE study.StudyDesignLabs ADD PI NVARCHAR(200); -ALTER TABLE study.StudyDesignLabs ADD Description TEXT; -ALTER TABLE study.StudyDesignLabs ADD Summary TEXT; -ALTER TABLE study.StudyDesignLabs ADD Institution NVARCHAR(200); - -CREATE TABLE study.TreatmentVisitMap -( - CohortId INT NOT NULL, - TreatmentId INT NOT NULL, - VisitId INT NOT NULL, - Container ENTITYID NOT NULL, - - CONSTRAINT PK_CohortId_TreatmentId_VisitId PRIMARY KEY (CohortId, TreatmentId, VisitId, Container) -); - -CREATE TABLE study.Objective -( - RowId INT IDENTITY(1, 1) NOT NULL, - Label NVARCHAR(200) NOT NULL, - Type NVARCHAR(200), - Description NTEXT, - DescriptionRendererType NVARCHAR(50) NOT NULL DEFAULT 'TEXT_WITH_LINKS', - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT PK_Objective PRIMARY KEY (RowId) -); - -CREATE TABLE study.VisitTag -( - Name NVARCHAR(200) NOT NULL, - Caption NVARCHAR(200) NOT NULL, - Description NVARCHAR(MAX), - SingleUse BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT PK_Name_Container PRIMARY KEY (Name, Container) -); - -ALTER TABLE study.VisitTag ADD Category NVARCHAR(200); - --- new tables for storing the assay schedule information -CREATE TABLE study.AssaySpecimen -( - RowId INT IDENTITY(1, 1) NOT NULL, - - Container ENTITYID NOT NULL, - Created DATETIME, - CreatedBy USERID, - Modified DATETIME, - ModifiedBy USERID, - - AssayName NVARCHAR(200), - Description NVARCHAR(200), - LocationId INTEGER, - Source NVARCHAR(20), - TubeType NVARCHAR(64), - PrimaryTypeId INTEGER, - DerivativeTypeId INTEGER, - - CONSTRAINT PK_AssaySpecimen PRIMARY KEY (Container, RowId) -); - -ALTER TABLE study.AssaySpecimen ADD Lab NVARCHAR(200); -ALTER TABLE study.AssaySpecimen ADD SampleType NVARCHAR(200); -ALTER TABLE study.AssaySpecimen ADD SampleQuantity DOUBLE PRECISION; -ALTER TABLE study.AssaySpecimen ADD SampleUnits NVARCHAR(5); -ALTER TABLE study.AssaySpecimen ADD DataSet INTEGER; - -CREATE TABLE study.AssaySpecimenVisit -( - RowId INT IDENTITY(1, 1) NOT NULL, - - Container ENTITYID NOT NULL, - Created DATETIME, - CreatedBy USERID, - Modified DATETIME, - ModifiedBy USERID, - - VisitId INTEGER, - AssaySpecimenId INTEGER, - - CONSTRAINT PK_AssaySpecimenVisit PRIMARY KEY (Container, RowId) -); -CREATE UNIQUE INDEX UQ_VisitAssaySpecimen ON study.AssaySpecimenVisit(Container, VisitId, AssaySpecimenId); -CREATE UNIQUE INDEX UQ_AssaySpecimenVisit ON study.AssaySpecimenVisit(Container, AssaySpecimenId, VisitId); - -CREATE TABLE study.VisitTagMap -( - RowId INT IDENTITY(1,1), - VisitTag NVARCHAR(200) NOT NULL, - VisitId INTEGER NOT NULL, - CohortId INTEGER, - Container ENTITYID NOT NULL, - CONSTRAINT PK_VisitTagMap PRIMARY KEY (Container, RowId), - CONSTRAINT VisitTagMap_Container_VisitTag_Key UNIQUE (Container, VisitTag, VisitId, CohortId) -); - -CREATE TABLE study.DoseAndRoute -( - RowId INT IDENTITY(1, 1) NOT NULL, - Label NVARCHAR(600), - Dose NVARCHAR(200), - Route NVARCHAR(200), - ProductId INT NOT NULL, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT PK_DoseAndRoute PRIMARY KEY (RowId) -); - -ALTER TABLE study.DoseAndRoute ADD CONSTRAINT DoseAndRoute_Container_Dose_Route_ProductId UNIQUE (Container, Dose, Route, ProductId); - -ALTER TABLE study.DoseAndRoute DROP COLUMN Label; - -CREATE TABLE study.StudyDesignChallengeTypes -( - Name NVARCHAR(200) NOT NULL, - Label NVARCHAR(200) NOT NULL, - Inactive BIT NOT NULL DEFAULT 0, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - Container ENTITYID NOT NULL, - - CONSTRAINT pk_studydesignchallengetypes PRIMARY KEY (Container, Name) -); - -ALTER TABLE study.study ADD FailForUndefinedTimepoints BIT NOT NULL DEFAULT 0; diff --git a/study/resources/schemas/dbscripts/sqlserver/study-25.000-25.001.sql b/study/resources/schemas/dbscripts/sqlserver/study-25.000-25.001.sql deleted file mode 100644 index 5afe8275435..00000000000 --- a/study/resources/schemas/dbscripts/sqlserver/study-25.000-25.001.sql +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ - -ALTER TABLE study.DataSet ADD SourceQueryName NVARCHAR(200); -ALTER TABLE study.DataSet ADD SourceQuerySchema NVARCHAR(200); -ALTER TABLE study.DataSet ADD SourceQueryContainer ENTITYID; \ No newline at end of file diff --git a/study/resources/schemas/dbscripts/sqlserver/study-25.001-25.002.sql b/study/resources/schemas/dbscripts/sqlserver/study-25.001-25.002.sql deleted file mode 100644 index 6a4e0339ebb..00000000000 --- a/study/resources/schemas/dbscripts/sqlserver/study-25.001-25.002.sql +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- "publish" is the only supported type now, so migrate any "ancillary" studies to "publish" -UPDATE study.StudySnapshot SET Type = 'publish'; diff --git a/study/resources/schemas/dbscripts/sqlserver/study-25.002-25.003.sql b/study/resources/schemas/dbscripts/sqlserver/study-25.002-25.003.sql deleted file mode 100644 index b5fef5c9aec..00000000000 --- a/study/resources/schemas/dbscripts/sqlserver/study-25.002-25.003.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ --- This index overlaps with ix_participant_currentcohort -DROP INDEX ix_participant_cohortid ON study.Participant; - diff --git a/study/resources/schemas/dbscripts/sqlserver/study-25.004-25.005.sql b/study/resources/schemas/dbscripts/sqlserver/study-25.004-25.005.sql deleted file mode 100644 index 8bfe1f7f46c..00000000000 --- a/study/resources/schemas/dbscripts/sqlserver/study-25.004-25.005.sql +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 - */ -ALTER TABLE study.uploadlog DROP CONSTRAINT UQ_UploadLog_FilePath; \ No newline at end of file diff --git a/study/resources/schemas/dbscripts/sqlserver/study-create.sql b/study/resources/schemas/dbscripts/sqlserver/study-create.sql deleted file mode 100644 index 5709517ee46..00000000000 --- a/study/resources/schemas/dbscripts/sqlserver/study-create.sql +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -CREATE VIEW study.LockedSpecimens AS - SELECT map.SpecimenGlobalUniqueId AS GlobalUniqueId, map.Container FROM study.SampleRequest AS request - JOIN study.SampleRequestStatus AS status ON request.StatusId = status.RowId AND status.SpecimensLocked = 1 - JOIN study.SampleRequestSpecimen AS map ON request.rowid = map.SampleRequestId AND map.Orphaned = 0 -GO - -CREATE VIEW study.ParticipantGroupCohortUnion AS - SELECT Container, - ParticipantId, - GroupId, - null AS CohortId, - CAST(GroupId AS NVARCHAR) + '-participantGroup' as UniqueId - FROM study.ParticipantGroupMap - UNION - SELECT Container, - ParticipantId, - null AS GroupId, - Currentcohortid AS CohortId, - CAST(CurrentCohortId AS NVARCHAR) + '-cohort' as UniqueId - FROM study.Participant; diff --git a/study/resources/schemas/dbscripts/sqlserver/study-drop.sql b/study/resources/schemas/dbscripts/sqlserver/study-drop.sql deleted file mode 100644 index c898d859883..00000000000 --- a/study/resources/schemas/dbscripts/sqlserver/study-drop.sql +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2008-2026 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - --- DROP all views (current and obsolete) - --- NOTE: Don't remove any of these drop statements, even if we stop re-creating the view in *-create.sql. Drop statements must --- remain in place so we can correctly upgrade from older versions, which we commit to for two years after each release. - --- Current views -EXEC core.fn_dropifexists 'LockedSpecimens', 'study', 'VIEW', NULL -EXEC core.fn_dropifexists 'ParticipantGroupCohortUnion', 'study', 'VIEW', NULL -GO diff --git a/study/src/org/labkey/study/model/CohortManager.java b/study/src/org/labkey/study/model/CohortManager.java index 07153ae4c4c..1e21c9c8f4f 100644 --- a/study/src/org/labkey/study/model/CohortManager.java +++ b/study/src/org/labkey/study/model/CohortManager.java @@ -284,13 +284,11 @@ public void clearParticipantCohorts(Study study) // null out cohort for all participants in this container: new SqlExecutor(ss).execute("UPDATE " + StudySchema.getInstance().getTableInfoParticipant() + - (ss.getSqlDialect().isSqlServer() ? " WITH (UPDLOCK)" : "") + "\nSET InitialCohortId = NULL, CurrentCohortId = NULL\nWHERE Container = ?", study.getContainer().getId()); // null out cohort for all participant/visits in this container (required for advanced cohort support, where participants // can change cohorts over time): new SqlExecutor(ss).execute("UPDATE " + StudySchema.getInstance().getTableInfoParticipantVisit() + - (ss.getSqlDialect().isSqlServer() ? " WITH (UPDLOCK)" : "") + "\nSET CohortId = NULL\nWHERE Container = ?", study.getContainer().getId()); StudyManager.getInstance().clearParticipantCache(study.getContainer()); diff --git a/study/src/org/labkey/study/model/StudyManager.java b/study/src/org/labkey/study/model/StudyManager.java index 77e59c501f4..48595f02f33 100644 --- a/study/src/org/labkey/study/model/StudyManager.java +++ b/study/src/org/labkey/study/model/StudyManager.java @@ -77,7 +77,6 @@ import org.labkey.api.data.TableInfo; import org.labkey.api.data.TableSelector; import org.labkey.api.data.UpdateableTableInfo; -import org.labkey.api.data.dialect.SqlDialect; import org.labkey.api.dataiterator.BeanDataIterator; import org.labkey.api.dataiterator.DataIteratorBuilder; import org.labkey.api.dataiterator.DataIteratorContext; @@ -1645,8 +1644,6 @@ public void deleteVisits(StudyImpl study, Collection visits, User use SQLFragment sqlf = new SQLFragment(); sqlf.append("DELETE FROM "); sqlf.append(t); - if (schema.getSqlDialect().isSqlServer()) - sqlf.append(" WITH (UPDLOCK)"); sqlf.append(" WHERE LSID IN (SELECT LSID FROM "); sqlf.append(t); sqlf.append(" d, "); @@ -3978,21 +3975,7 @@ public VisitManager getVisitManager(Study study) public static SQLFragment timePortionFromDateSQL(String dateColumnName) { - SqlDialect dialect = StudySchema.getInstance().getSqlDialect(); - SQLFragment sql = new SQLFragment(); - if (dialect.isPostgreSQL()) - { - sql.append("to_char(").append(dateColumnName).append(", 'HH24MISS')"); - } - else if (dialect.isSqlServer()) - { - sql.append("FORMAT(").append(dateColumnName).append(", 'HHmmss')"); - } - else - { - sql.append("CAST((").append(dateColumnName).append(") AS VARCHAR(10))"); - } - return sql; + return new SQLFragment("to_char(").append(dateColumnName).append(", 'HH24MISS')"); } private String getParticipantCacheKey(Container container) diff --git a/study/src/org/labkey/study/query/BaseStudyTable.java b/study/src/org/labkey/study/query/BaseStudyTable.java index 4783615c2c1..490b6e955cb 100644 --- a/study/src/org/labkey/study/query/BaseStudyTable.java +++ b/study/src/org/labkey/study/query/BaseStudyTable.java @@ -497,8 +497,6 @@ public void declareJoins(String parentAlias, Map map) specimenCommentJoin(parentAlias, map); } }).setHidden(true); - if (getSqlDialect().isSqlServer()) - field = "CAST((" + field + ") AS VARCHAR(500))"; commentFields.add(new Pair<>(field, "'Vial: '")); } if (ptidCommentTable != null && ptidCommentAlias != null) @@ -594,8 +592,7 @@ private void appendCommentCaseSQL(StringBuilder sb, List> f for (int i = 0; i < fields.size(); i++) { - castFields[i] = "CAST((" + getSqlDialect().concatenate(sep, fields.get(i).second, fields.get(i).first) + ") AS VARCHAR" + - (getSqlDialect().isSqlServer() ? "(500)" : "") + ")"; + castFields[i] = "CAST((" + getSqlDialect().concatenate(sep, fields.get(i).second, fields.get(i).first) + ") AS VARCHAR)"; sep = "', '"; } diff --git a/study/src/org/labkey/study/query/LocationTable.java b/study/src/org/labkey/study/query/LocationTable.java index 83d7d627203..6ae742ff597 100644 --- a/study/src/org/labkey/study/query/LocationTable.java +++ b/study/src/org/labkey/study/query/LocationTable.java @@ -261,8 +261,6 @@ private SQLFragment getLocationInUseExpression(String locationTableAlias) var inUseColumn = getRealTable().getColumn("InUse"); SQLFragment existsSQL = new SQLFragment(); existsSQL.append(inUseColumn.getValueSql(locationTableAlias)); - if (schema.getSqlDialect().isSqlServer()) - existsSQL.append(" = 1"); existsSQL .append(" OR\n") diff --git a/study/src/org/labkey/study/visitmanager/RelativeDateVisitManager.java b/study/src/org/labkey/study/visitmanager/RelativeDateVisitManager.java index 4180c5e627e..bfbdced499f 100644 --- a/study/src/org/labkey/study/visitmanager/RelativeDateVisitManager.java +++ b/study/src/org/labkey/study/visitmanager/RelativeDateVisitManager.java @@ -223,11 +223,7 @@ protected void updateParticipantVisitTable(@Nullable User user, @Nullable Logger .append(" AND ").append(tableParticipant.getColumn("Container").getValueSql(tableParticipantSelectName)) .append("=").append(tableParticipantVisit.getColumn("Container").getValueSql(tableParticipantVisitSelectName)).append(")"); - SQLFragment sqlVisitDate = new SQLFragment("CAST(VisitDate AS DATE)"); - if (schema.getSqlDialect().isPostgreSQL()) - { - sqlVisitDate.append("::TIMESTAMP"); - } + SQLFragment sqlVisitDate = new SQLFragment("CAST(VisitDate AS DATE)::TIMESTAMP"); sqlStartDate = new SQLFragment("CAST(").append(sqlStartDate).append(" AS DATE)"); SQLFragment sqlUpdateDays = new SQLFragment("UPDATE "); diff --git a/study/src/org/labkey/study/visitmanager/SequenceVisitManager.java b/study/src/org/labkey/study/visitmanager/SequenceVisitManager.java index c8fa1bd8d09..9b4a0ce0beb 100644 --- a/study/src/org/labkey/study/visitmanager/SequenceVisitManager.java +++ b/study/src/org/labkey/study/visitmanager/SequenceVisitManager.java @@ -342,18 +342,13 @@ private void _updateVisitDate(User user) { TableInfo tableStudyDataFiltered = StudySchema.getInstance().getTableInfoStudyDataFiltered(getStudy(), defsWithVisitDates, user); SQLFragment sqlUpdateVisitDates = new SQLFragment(); - sqlUpdateVisitDates.append("UPDATE ").append(tableParticipantVisit); - if (!schema.getSqlDialect().isSqlServer()) - sqlUpdateVisitDates.append(" PV"); // For Postgres put "PV" here + sqlUpdateVisitDates.append("UPDATE ").append(tableParticipantVisit).append(" PV"); sqlUpdateVisitDates.append("\n").append("SET VisitDate = _VisitDate, Day = _VisitDay FROM\n") .append(" (\n") .append(" SELECT DISTINCT _VisitDate, _VisitDay, SequenceNum, ParticipantId, DatasetId\n") .append(" FROM ").append(tableStudyDataFiltered.getFromSQL("SD1")).append(") SD, ") .append(tableVisit.getFromSQL("V")); - if (schema.getSqlDialect().isSqlServer()) - sqlUpdateVisitDates.append(", ").append(tableParticipantVisit.getFromSQL("PV")); // Have to put the "PV" here for MSSQL - sqlUpdateVisitDates.append("\n WHERE PV.VisitRowId = V.RowId AND") // 'join' V .append(" SD.ParticipantId = PV.ParticipantId AND SD.SequenceNum = PV.SequenceNum AND\n") // 'join' SD .append(" SD.DatasetId = V.VisitDateDatasetId AND V.Container = ? AND PV.Container = ?\n"); @@ -413,18 +408,13 @@ private void _updateVisitDate(User user, DatasetDefinition def, @Nullable Logger // update ParticipantVisit.VisitDate based on declared Visit.visitDateDatasetId TableInfo tableStudyDataFiltered = StudySchema.getInstance().getTableInfoStudyDataFiltered(getStudy(), Collections.singleton(def), user); SQLFragment sqlUpdateVisitDates = new SQLFragment(); - sqlUpdateVisitDates.append("UPDATE ").append(tableParticipantVisit); - if (!schema.getSqlDialect().isSqlServer()) - sqlUpdateVisitDates.append(" PV"); // For Postgres put "PV" here + sqlUpdateVisitDates.append("UPDATE ").append(tableParticipantVisit).append(" PV"); sqlUpdateVisitDates.append("\n").append("SET VisitDate = _VisitDate, Day = _VisitDay FROM\n") .append(" (\n") .append(" SELECT DISTINCT _VisitDate, _VisitDay, SequenceNum, ParticipantId, DatasetId\n") .append(" FROM ").append(tableStudyDataFiltered.getFromSQL("SD1")).append(") SD, ") .append(tableVisit.getFromSQL("V")); - if (schema.getSqlDialect().isSqlServer()) - sqlUpdateVisitDates.append(", ").append(tableParticipantVisit.getFromSQL("PV")); // Have to put the "PV" here for MSSQL - sqlUpdateVisitDates.append("\n WHERE PV.VisitRowId = V.RowId AND") // 'join' V .append(" SD.ParticipantId = PV.ParticipantId AND SD.SequenceNum = PV.SequenceNum AND\n") // 'join' SD .append(" ? = V.VisitDateDatasetId AND V.Container = ? AND PV.Container = ?\n"); @@ -475,24 +465,12 @@ private void _updateVisitRowId(boolean updateAll, @Nullable Logger logger) // updating a column to the existing value SQLFragment sqlUpdateVisitRowId = new SQLFragment(); sqlUpdateVisitRowId.append(seqnum2visit); - if (schema.getSqlDialect().isPostgreSQL()) - { - sqlUpdateVisitRowId.append( - "UPDATE study.ParticipantVisit PV\n" + - " SET VisitRowId = RowId\n" + - " FROM seqnum2visit\n" + - " WHERE seqnum2visit.SequenceNum = PV.SequenceNum AND PV.Container = ? AND seqnum2visit.RowId <> VisitRowId"); - sqlUpdateVisitRowId.add(getStudy().getContainer()); - } - else - { - sqlUpdateVisitRowId.append( - "UPDATE PV\n" + - " SET VisitRowId = RowId\n" + - " FROM study.ParticipantVisit PV WITH (INDEX(ix_participantvisit_sequencenum)), seqnum2visit\n"+ - " WHERE seqnum2visit.SequenceNum = PV.SequenceNum AND PV.Container = ? AND seqnum2visit.RowId <> VisitRowId"); - sqlUpdateVisitRowId.add(getStudy().getContainer()); - } + sqlUpdateVisitRowId.append( + "UPDATE study.ParticipantVisit PV\n" + + " SET VisitRowId = RowId\n" + + " FROM seqnum2visit\n" + + " WHERE seqnum2visit.SequenceNum = PV.SequenceNum AND PV.Container = ? AND seqnum2visit.RowId <> VisitRowId"); + sqlUpdateVisitRowId.add(getStudy().getContainer()); if (!updateAll) sqlUpdateVisitRowId.append(" AND VisitRowId=-1"); diff --git a/study/src/org/labkey/study/visitmanager/VisitManager.java b/study/src/org/labkey/study/visitmanager/VisitManager.java index 54ae69c74cd..7fa1f0d681b 100644 --- a/study/src/org/labkey/study/visitmanager/VisitManager.java +++ b/study/src/org/labkey/study/visitmanager/VisitManager.java @@ -748,8 +748,6 @@ protected int purgeParticipantsFromParticipantsVisitTable(Container c) SQLFragment sqlDelete = new SQLFragment(); sqlDelete.appendComment("", study.getSqlDialect()); sqlDelete.append("DELETE FROM study.ParticipantVisit"); - if (study.getSqlDialect().isSqlServer()) - sqlDelete.append(" WITH (UPDLOCK)"); sqlDelete.append(" WHERE Container = ? AND ParticipantId IN ("); sqlDelete.add(c); sqlDelete.append(sqlSelect); diff --git a/study/test/src/org/labkey/test/tests/study/AssayTest.java b/study/test/src/org/labkey/test/tests/study/AssayTest.java index db8a313c1ff..7d4e2865e3d 100644 --- a/study/test/src/org/labkey/test/tests/study/AssayTest.java +++ b/study/test/src/org/labkey/test/tests/study/AssayTest.java @@ -17,7 +17,6 @@ package org.labkey.test.tests.study; import org.assertj.core.api.Assertions; -import org.junit.Assume; import org.junit.Test; import org.junit.experimental.categories.Category; import org.labkey.api.util.FileUtil; @@ -134,7 +133,6 @@ public void testAssayNameMaxLength() throws Exception @Test public void testAssayMultiFileImportForMVTC() throws Exception { - Assume.assumeTrue("Multi-choice text fields are only supported on PostgreSQL", WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL); _containerHelper.createProject(MVTC_MULTI_FILE_IMPORT_PROJECT, "Assay"); new GeneralAssayDesign(MVTC_MULTI_FILE_IMPORT_ASSAY) .setRunFields(List.of(new FieldDefinition("runText", FieldDefinition.ColumnType.String)), true) diff --git a/study/test/src/org/labkey/test/tests/study/SCHARPStudyTest.java b/study/test/src/org/labkey/test/tests/study/SCHARPStudyTest.java index e204af02b8f..f83301af977 100644 --- a/study/test/src/org/labkey/test/tests/study/SCHARPStudyTest.java +++ b/study/test/src/org/labkey/test/tests/study/SCHARPStudyTest.java @@ -22,7 +22,6 @@ import org.labkey.test.TestFileUtils; import org.labkey.test.categories.Daily; import org.labkey.test.util.LogMethod; -import org.labkey.test.util.PostgresOnlyTest; import java.io.File; import java.util.Arrays; @@ -33,7 +32,7 @@ @Category({Daily.class}) @BaseWebDriverTest.ClassTimeout(minutes = 6) -public class SCHARPStudyTest extends BaseWebDriverTest implements PostgresOnlyTest +public class SCHARPStudyTest extends BaseWebDriverTest { public static final String PROJECT_NAME="SCHARP Study Test"; diff --git a/study/test/src/org/labkey/test/tests/study/StudyDatasetIndexTest.java b/study/test/src/org/labkey/test/tests/study/StudyDatasetIndexTest.java index b2ff3bc6c72..33ecf55b8b4 100644 --- a/study/test/src/org/labkey/test/tests/study/StudyDatasetIndexTest.java +++ b/study/test/src/org/labkey/test/tests/study/StudyDatasetIndexTest.java @@ -45,7 +45,6 @@ public class StudyDatasetIndexTest extends StudyBaseTest private static final File STUDY_WITH_DATASET_INDEX = TestFileUtils.getSampleData("studies/StudyWithDatasetIndex.folder.zip"); private static final File STUDY_WITH_DATASET_SHARED_INDEX = TestFileUtils.getSampleData("studies/StudyWithDatasetSharedIndex.folder.zip"); private static final String METADATA = "Table Meta Data"; - boolean IS_POSTGRES = WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL; @Override protected String getProjectName() @@ -205,10 +204,8 @@ private void verifyTableIndices(String prefix, List indexSuffixes) private void verifyTableIndexNonUnique(String prefix, String suffix, boolean isUnique) { - String boolDisplay = isUnique ? "0" : "1"; - if (IS_POSTGRES) boolDisplay = isUnique ? "false" : "true"; - String fieldKey = prefix + suffix; - if (IS_POSTGRES) fieldKey = fieldKey.toLowerCase(); + String boolDisplay = isUnique ? "false" : "true"; + String fieldKey = (prefix + suffix).toLowerCase(); Locator locator = Locator.xpath("//td[contains(text(), '" + fieldKey + "')]/preceding-sibling::td[2][text()='" + boolDisplay + "']"); checker().verifyTrue("Non_Unique value not as expected in metadata for locator: " + locator, locator.existsIn(getDriver())); } diff --git a/study/test/src/org/labkey/test/tests/study/StudyDatasetsTest.java b/study/test/src/org/labkey/test/tests/study/StudyDatasetsTest.java index 3ecc2ab0049..b6106fe3975 100644 --- a/study/test/src/org/labkey/test/tests/study/StudyDatasetsTest.java +++ b/study/test/src/org/labkey/test/tests/study/StudyDatasetsTest.java @@ -17,7 +17,6 @@ package org.labkey.test.tests.study; import org.jetbrains.annotations.Nullable; -import org.junit.Assume; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; @@ -188,7 +187,6 @@ public void testDatasets() @Test public void testDatasetWithMultiChoice() { - Assume.assumeTrue("Multi-choice text fields are only supported on PostgreSQL", WebTestHelper.getDatabaseType() == WebTestHelper.DatabaseType.PostgreSQL); String datasetName = "Test dataset"; DatasetDesignerPage definitionPage = _studyHelper.goToManageDatasets() .clickCreateNewDataset() diff --git a/study/test/src/org/labkey/test/tests/study/StudyDataspaceTest.java b/study/test/src/org/labkey/test/tests/study/StudyDataspaceTest.java index 10314779000..f3320a8557d 100644 --- a/study/test/src/org/labkey/test/tests/study/StudyDataspaceTest.java +++ b/study/test/src/org/labkey/test/tests/study/StudyDataspaceTest.java @@ -33,7 +33,6 @@ import org.labkey.test.util.Ext4Helper; import org.labkey.test.util.LogMethod; import org.labkey.test.util.PortalHelper; -import org.labkey.test.util.PostgresOnlyTest; import org.labkey.test.util.StudyHelper; import org.openqa.selenium.WebElement; @@ -46,7 +45,7 @@ @Category({Daily.class}) @BaseWebDriverTest.ClassTimeout(minutes = 15) -public class StudyDataspaceTest extends StudyBaseTest implements PostgresOnlyTest +public class StudyDataspaceTest extends StudyBaseTest { protected final String FOLDER_STUDY1 = "Study 1"; protected final String FOLDER_STUDY2 = "Study 2"; diff --git a/study/test/src/org/labkey/test/tests/study/StudyProtocolDesignerTest.java b/study/test/src/org/labkey/test/tests/study/StudyProtocolDesignerTest.java index 70875b39dc0..0680c708cd2 100644 --- a/study/test/src/org/labkey/test/tests/study/StudyProtocolDesignerTest.java +++ b/study/test/src/org/labkey/test/tests/study/StudyProtocolDesignerTest.java @@ -40,7 +40,6 @@ import org.labkey.test.components.studydesigner.VaccineDesignWebpart; import org.labkey.test.util.LogMethod; import org.labkey.test.util.PortalHelper; -import org.labkey.test.util.PostgresOnlyTest; import org.labkey.test.util.TestDataGenerator; import org.openqa.selenium.WebElement; @@ -59,7 +58,7 @@ @Category({Daily.class}) @BaseWebDriverTest.ClassTimeout(minutes = 9) -public class StudyProtocolDesignerTest extends BaseWebDriverTest implements PostgresOnlyTest +public class StudyProtocolDesignerTest extends BaseWebDriverTest { private static final File STUDY_ARCHIVE = TestFileUtils.getSampleData("studies/CohortStudy.zip"); // Cohorts: defined in folder archive diff --git a/survey/module.properties b/survey/module.properties index df191053b11..672bc8c3833 100644 --- a/survey/module.properties +++ b/survey/module.properties @@ -7,5 +7,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/survey/resources/schemas/dbscripts/sqlserver/survey-0.00-13.10.sql b/survey/resources/schemas/dbscripts/sqlserver/survey-0.00-13.10.sql deleted file mode 100644 index d4a9ae38d16..00000000000 --- a/survey/resources/schemas/dbscripts/sqlserver/survey-0.00-13.10.sql +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2013-2019 LabKey Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* survey-0.00-0.01.sql */ - --- Create schema, tables, indexes, and constraints used for Survey module here --- All SQL VIEW definitions should be created in survey-create.sql and dropped in survey-drop.sql -CREATE SCHEMA survey; -GO - -CREATE TABLE survey.SurveyDesigns -( - RowId INT IDENTITY(1,1) NOT NULL, - Container ENTITYID NOT NULL, - Label NVARCHAR(200) NOT NULL, - - CreatedBy USERID, - Created DATETIME, - ModifiedBy USERID, - Modified DATETIME, - - -- the schema for the results - QueryName NVARCHAR(200), - SchemaName NVARCHAR(50), - - -- the survey questions - Metadata TEXT, - - CONSTRAINT pk_surveyDesigns PRIMARY KEY (RowId) -); - -CREATE TABLE survey.Surveys -( - RowId INT IDENTITY(1,1) NOT NULL, - Container ENTITYID NOT NULL, - EntityId ENTITYID NOT NULL, - Label NVARCHAR(200) NOT NULL, - - CreatedBy USERID, - Created DATETIME, - SubmittedBy USERID, - Submitted DATETIME, - ModifiedBy USERID, - Modified DATETIME, - - Status NVARCHAR(50), - SurveyDesignId INT NOT NULL, - - -- the rowPk which holds the responses - ResponsesPk NVARCHAR(200), - - CONSTRAINT pk_surveys PRIMARY KEY (RowId), - CONSTRAINT fk_surveys_surveyDesignId FOREIGN KEY (SurveyDesignId) REFERENCES survey.SurveyDesigns (RowId) -); - -/* survey-12.30-13.10.sql */ - -ALTER TABLE survey.SurveyDesigns ADD Description NTEXT; \ No newline at end of file diff --git a/timeline/module.properties b/timeline/module.properties index 455fff60ce9..2ae5d7190fc 100644 --- a/timeline/module.properties +++ b/timeline/module.properties @@ -5,5 +5,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/visualization/module.properties b/visualization/module.properties index c131631603d..f9f364b4fa1 100644 --- a/visualization/module.properties +++ b/visualization/module.properties @@ -7,5 +7,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true diff --git a/wiki/module.properties b/wiki/module.properties index 660b15e57cc..07f573cbd1c 100644 --- a/wiki/module.properties +++ b/wiki/module.properties @@ -8,5 +8,4 @@ Organization: LabKey OrganizationURL: https://www.labkey.com/ License: Apache 2.0 LicenseURL: http://www.apache.org/licenses/LICENSE-2.0 -SupportedDatabases: mssql, pgsql ManageVersion: true