diff --git a/resources/queries/snd/LookupSets.query.xml b/resources/queries/snd/LookupSets.query.xml new file mode 100644 index 00000000..65b07f1a --- /dev/null +++ b/resources/queries/snd/LookupSets.query.xml @@ -0,0 +1,17 @@ + + + + + SetName + + + true + + + true + + +
+
+
+
\ No newline at end of file diff --git a/resources/queries/snd/LookupSets/.qview.xml b/resources/queries/snd/LookupSets/.qview.xml new file mode 100644 index 00000000..02898e37 --- /dev/null +++ b/resources/queries/snd/LookupSets/.qview.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/resources/queries/snd/Lookups.js b/resources/queries/snd/Lookups.js index 36408406..177cebbb 100644 --- a/resources/queries/snd/Lookups.js +++ b/resources/queries/snd/Lookups.js @@ -45,11 +45,6 @@ function beforeUpdate(row, errors) { } function beforeDelete(row, errors) { -/* - TODO: Need a better way to determine if a lookupset item is in use. Probably need to add the check to - the deleteRows method in LookupsTable.java. NOTE: CAMP allows the lookup item to be deleted if it hasn't - been assigned as a default value or used in an event. tjh - */ if (row.LookupSetId !== undefined) { let lookupQuery @@ -81,18 +76,17 @@ function beforeDelete(row, errors) { LABKEY.Query.selectRows({ schemaName: 'snd', - queryName: 'PackageAttribute', - columns: 'LookupQuery', + queryName: 'Lookups', + columns: 'IsInUse', scope: this, filterArray: [ - LABKEY.Filter.create('LookupQuery', lookupQuery, LABKEY.Filter.Types.EQUAL), - LABKEY.Filter.create('LookupSchema', 'snd', LABKEY.Filter.Types.EQUAL) + LABKEY.Filter.create('LookupId', row["LookupId"], LABKEY.Filter.Types.EQUAL), + LABKEY.Filter.create('IsInUse', 'true', LABKEY.Filter.Types.EQUAL) ], success: function (data) { if (data.rows && data.rows.length) { - errors._form = 'Lookup item cannot be deleted - LookupSet is in use.' - return; + errors._form = 'Lookup item cannot be deleted - Lookup is in use.' } }, failure: function (error) { diff --git a/resources/queries/snd/Lookups.query.xml b/resources/queries/snd/Lookups.query.xml index c08dfb5c..c4b5d0b1 100644 --- a/resources/queries/snd/Lookups.query.xml +++ b/resources/queries/snd/Lookups.query.xml @@ -3,6 +3,17 @@ Value + + + true + + + true + + + true + +
diff --git a/resources/queries/snd/Lookups/.qview.xml b/resources/queries/snd/Lookups/.qview.xml new file mode 100644 index 00000000..6dec6876 --- /dev/null +++ b/resources/queries/snd/Lookups/.qview.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/resources/schemas/dbscripts/sqlserver/snd-23.001-23.003.sql b/resources/schemas/dbscripts/sqlserver/snd-23.001-23.003.sql new file mode 100644 index 00000000..09295734 --- /dev/null +++ b/resources/schemas/dbscripts/sqlserver/snd-23.001-23.003.sql @@ -0,0 +1,2 @@ +CREATE UNIQUE INDEX IDX_LookupSets_SetName +ON snd.LookupSets (SetName) \ No newline at end of file diff --git a/src/org/labkey/snd/SNDManager.java b/src/org/labkey/snd/SNDManager.java index 3a0077e9..16edff8c 100644 --- a/src/org/labkey/snd/SNDManager.java +++ b/src/org/labkey/snd/SNDManager.java @@ -3380,5 +3380,5 @@ public List> getProjectItemsList(Container c, User u, int pr return projectItems; } - + } \ No newline at end of file diff --git a/src/org/labkey/snd/SNDModule.java b/src/org/labkey/snd/SNDModule.java index 7d1e5ab6..b44f0cea 100644 --- a/src/org/labkey/snd/SNDModule.java +++ b/src/org/labkey/snd/SNDModule.java @@ -65,7 +65,7 @@ public String getName() @Override public @Nullable Double getSchemaVersion() { - return 23.001; + return 23.003; } @Override diff --git a/src/org/labkey/snd/SNDSchema.java b/src/org/labkey/snd/SNDSchema.java index eb5065eb..385874b0 100644 --- a/src/org/labkey/snd/SNDSchema.java +++ b/src/org/labkey/snd/SNDSchema.java @@ -112,10 +112,7 @@ public TableInfo getTableInfoLookups() return getSchema().getTable(LOOKUPS_TABLE_NAME); } - public TableInfo getTableInfoLookupSets() - { - return getSchema().getTable(LOOKUPSETS_TABLE_NAME); - } + public TableInfo getTableInfoLookupSets() { return getSchema().getTable(LOOKUPSETS_TABLE_NAME); } public TableInfo getTableInfoEventsCache() { diff --git a/src/org/labkey/snd/SNDUserSchema.java b/src/org/labkey/snd/SNDUserSchema.java index 4b914a58..a8f318cb 100644 --- a/src/org/labkey/snd/SNDUserSchema.java +++ b/src/org/labkey/snd/SNDUserSchema.java @@ -38,6 +38,7 @@ import org.labkey.snd.query.EventsCacheTable; import org.labkey.snd.query.EventsTable; import org.labkey.snd.query.LookupSetsTable; +import org.labkey.snd.query.LookupSetsVirtualTable; import org.labkey.snd.query.LookupsTable; import org.labkey.snd.query.PackageAttributeTable; import org.labkey.snd.query.PackagesTable; @@ -203,11 +204,7 @@ public TableInfo createTable(SNDUserSchema schema, ContainerFilter cf) @Override public TableInfo createTable(SNDUserSchema schema, ContainerFilter cf) { - SimpleUserSchema.SimpleTable table = - new SimpleUserSchema.SimpleTable<>( - schema, SNDSchema.getInstance().getTableInfoLookupSets(), cf).init(); - - return table; + return new LookupSetsTable(schema, SNDSchema.getInstance().getTableInfoLookupSets(), cf).init(); } }, EventsCache @@ -254,7 +251,7 @@ public TableInfo createTable(String name, ContainerFilter cf) if (nameMap.containsKey(name)) { TableInfo table = SNDSchema.getInstance().getTableInfoLookups(); - return new LookupSetsTable(this, table, name, nameMap.get(name), cf).init(); + return new LookupSetsVirtualTable(this, table, name, nameMap.get(name), cf).init(); } } } @@ -263,7 +260,7 @@ public TableInfo createTable(String name, ContainerFilter cf) public Map> getLookupSets() { - Map> nameMap = SNDManager.get().getCache().get(LookupSetsTable.getCacheKey(getContainer())); + Map> nameMap = SNDManager.get().getCache().get(LookupSetsVirtualTable.getCacheKey(getContainer())); if (nameMap != null) return nameMap; @@ -283,7 +280,7 @@ public Map> getLookupSets() } nameMap = Collections.unmodifiableMap(nameMap); - SNDManager.get().getCache().put(LookupSetsTable.getCacheKey(getContainer()), nameMap); + SNDManager.get().getCache().put(LookupSetsVirtualTable.getCacheKey(getContainer()), nameMap); return nameMap; } diff --git a/src/org/labkey/snd/query/LookupSetsTable.java b/src/org/labkey/snd/query/LookupSetsTable.java index 82461af0..f4f3666e 100644 --- a/src/org/labkey/snd/query/LookupSetsTable.java +++ b/src/org/labkey/snd/query/LookupSetsTable.java @@ -1,70 +1,42 @@ -/* - * Copyright (c) 2018-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. - */ package org.labkey.snd.query; -import org.labkey.api.data.ColumnInfo; -import org.labkey.api.data.Container; import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.JdbcType; +import org.labkey.api.data.SQLFragment; import org.labkey.api.data.TableInfo; +import org.labkey.api.query.ExprColumn; import org.labkey.api.query.SimpleUserSchema.SimpleTable; +import org.labkey.snd.SNDSchema; import org.labkey.snd.SNDUserSchema; -import java.util.Map; +public class LookupSetsTable extends SimpleTable { -/** - * Created by marty on 9/17/2017. - */ -public class LookupSetsTable extends SimpleTable -{ - private static final String CACHE_KEY = LookupSetsTable.class.getName() + "||values"; - private static final String SETNAME_COL = "SetName"; - private static final String LABEL_COL = "Label"; - private static final String DESCRIPTION_COL = "Description"; - private static final String LOOKUPSETID_COL = "LookupSetId"; - private Integer _lookupSetId; - - - public LookupSetsTable(SNDUserSchema schema, TableInfo table, String setName, Map map, ContainerFilter cf) - { - super(schema, table, cf); - - _lookupSetId = (Integer) map.get(LOOKUPSETID_COL); - - if (map.containsKey(LABEL_COL)) - setTitle((String)map.get(LABEL_COL)); - - if (map.containsKey(DESCRIPTION_COL)) - setDescription((String) map.get(DESCRIPTION_COL)); - - } - - public static String getCacheKey(Container c) - { - return CACHE_KEY + "||" + c.getId(); - } + /** + * Create the simple table. + * SimpleTable doesn't add columns until .init() has been called to allow derived classes to fully initialize themselves before adding columns. + * + * @param schema + * @param table + */ + public LookupSetsTable(SNDUserSchema schema, TableInfo table, ContainerFilter cf) { super(schema, table, cf); } @Override - public LookupSetsTable init() - { + public LookupSetsTable init() { super.init(); - ColumnInfo col = getRealTable().getColumn(LOOKUPSETID_COL); - addCondition(col, _lookupSetId); + SQLFragment isInUseQuery = new SQLFragment(); + isInUseQuery.append("(CASE WHEN EXISTS (SELECT ls.SetName FROM "); + isInUseQuery.append(SNDSchema.getInstance().getTableInfoLookupSets(), "ls"); + isInUseQuery.append(" INNER JOIN "); + isInUseQuery.append(_userSchema.getTable("PackageAttribute").getFromSQL("pa")); + isInUseQuery.append(" ON ls.SetName = pa.LookupQuery "); + isInUseQuery.append(" WHERE " + ExprColumn.STR_TABLE_ALIAS + ".LookupSetId = ls.LookupSetId) "); + isInUseQuery.append(" THEN 'true' else 'false' END)"); + ExprColumn isInUseColumn = new ExprColumn(this, "IsInUse", isInUseQuery, JdbcType.BOOLEAN); + addColumn(isInUseColumn); return this; } } + diff --git a/src/org/labkey/snd/query/LookupSetsVirtualTable.java b/src/org/labkey/snd/query/LookupSetsVirtualTable.java new file mode 100644 index 00000000..86216370 --- /dev/null +++ b/src/org/labkey/snd/query/LookupSetsVirtualTable.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2018-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. + */ +package org.labkey.snd.query; + +import org.labkey.api.data.ColumnInfo; +import org.labkey.api.data.Container; +import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.JdbcType; +import org.labkey.api.data.SQLFragment; +import org.labkey.api.data.TableInfo; +import org.labkey.api.query.ExprColumn; +import org.labkey.api.query.SimpleUserSchema.SimpleTable; +import org.labkey.snd.SNDSchema; +import org.labkey.snd.SNDUserSchema; + +import java.util.Map; + +/** + * Created by marty on 9/17/2017. + */ +public class LookupSetsVirtualTable extends SimpleTable +{ + private static final String CACHE_KEY = LookupSetsVirtualTable.class.getName() + "||values"; + private static final String SETNAME_COL = "SetName"; + private static final String LABEL_COL = "Label"; + private static final String DESCRIPTION_COL = "Description"; + private static final String LOOKUPSETID_COL = "LookupSetId"; + private Integer _lookupSetId; + + + public LookupSetsVirtualTable(SNDUserSchema schema, TableInfo table, String setName, Map map, ContainerFilter cf) + { + super(schema, table, cf); + + _lookupSetId = (Integer) map.get(LOOKUPSETID_COL); + + if (map.containsKey(LABEL_COL)) + setTitle((String)map.get(LABEL_COL)); + + if (map.containsKey(DESCRIPTION_COL)) + setDescription((String) map.get(DESCRIPTION_COL)); + + } + + public static String getCacheKey(Container c) + { + return CACHE_KEY + "||" + c.getId(); + } + + @Override + public LookupSetsVirtualTable init() + { + super.init(); + + ColumnInfo col = getRealTable().getColumn(LOOKUPSETID_COL); + addCondition(col, _lookupSetId); + + return this; + } + +} diff --git a/src/org/labkey/snd/query/LookupsTable.java b/src/org/labkey/snd/query/LookupsTable.java index e958bbea..0537a746 100644 --- a/src/org/labkey/snd/query/LookupsTable.java +++ b/src/org/labkey/snd/query/LookupsTable.java @@ -18,20 +18,31 @@ import org.jetbrains.annotations.Nullable; import org.labkey.api.data.Container; import org.labkey.api.data.ContainerFilter; +import org.labkey.api.data.JdbcType; +import org.labkey.api.data.SQLFragment; +import org.labkey.api.data.SimpleFilter; import org.labkey.api.data.TableInfo; +import org.labkey.api.data.TableSelector; import org.labkey.api.dataiterator.DataIteratorBuilder; +import org.labkey.api.exp.OntologyManager; import org.labkey.api.query.BatchValidationException; +import org.labkey.api.query.ExprColumn; +import org.labkey.api.query.FieldKey; import org.labkey.api.query.InvalidKeyException; import org.labkey.api.query.QueryUpdateService; import org.labkey.api.query.QueryUpdateServiceException; import org.labkey.api.query.SimpleUserSchema.SimpleTable; import org.labkey.api.security.User; +import org.labkey.api.settings.AppProps; import org.labkey.snd.SNDManager; +import org.labkey.snd.SNDSchema; import org.labkey.snd.SNDUserSchema; import java.sql.SQLException; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; public class LookupsTable extends SimpleTable { @@ -47,6 +58,32 @@ public LookupsTable(SNDUserSchema schema, TableInfo table, ContainerFilter cf) super(schema, table, cf); } + @Override + public LookupsTable init() { + super.init(); + + SQLFragment isInUseQuery = new SQLFragment(); + isInUseQuery.append("(CASE WHEN EXISTS (SELECT l.Value FROM "); + isInUseQuery.append(SNDSchema.getInstance().getTableInfoLookups(), "l"); + isInUseQuery.append(" INNER JOIN "); + isInUseQuery.append(SNDSchema.getInstance().getTableInfoLookupSets(), "ls"); + isInUseQuery.append(" ON l.LookupSetId = ls.LookupSetId "); + isInUseQuery.append(" INNER JOIN "); + isInUseQuery.append(OntologyManager.getTinfoPropertyDescriptor(), "pd"); + isInUseQuery.append(" ON ls.SetName = pd.LookupQuery "); + isInUseQuery.append(" AND pd.PropertyURI LIKE ? "); + isInUseQuery.append(" INNER JOIN "); + isInUseQuery.append(OntologyManager.getTinfoObjectProperty(), "op"); + isInUseQuery.append(" ON op.PropertyId = pd.PropertyId "); + isInUseQuery.append(" WHERE CAST(" + ExprColumn.STR_TABLE_ALIAS + ".LookupId AS FLOAT) = op.FloatValue) "); + isInUseQuery.append(" THEN 'true' else 'false' END)"); + isInUseQuery.add("urn:lsid:" + AppProps.getInstance().getDefaultLsidAuthority() + ":package-snd.Folder-%"); + ExprColumn isInUseColumn = new ExprColumn(this, "IsInUse", isInUseQuery, JdbcType.BOOLEAN); + addColumn(isInUseColumn); + + return this; + } + @Override public QueryUpdateService getUpdateService() {