From 06388635b5074742ee30d1574f8068f4e120bfdc Mon Sep 17 00:00:00 2001 From: XingY Date: Tue, 14 Apr 2026 22:52:37 -0700 Subject: [PATCH] GitHub Issue 1058: Sample Finder saved views in subfolder break after MVTC to TC conversion --- .../org/labkey/api/query/QueryService.java | 5 +- .../query/CustomViewQueryChangeListener.java | 18 ++--- .../org/labkey/query/QueryServiceImpl.java | 68 +++++++++++++++++++ 3 files changed, 81 insertions(+), 10 deletions(-) diff --git a/api/src/org/labkey/api/query/QueryService.java b/api/src/org/labkey/api/query/QueryService.java index f4506494969..99b848ada02 100644 --- a/api/src/org/labkey/api/query/QueryService.java +++ b/api/src/org/labkey/api/query/QueryService.java @@ -154,11 +154,14 @@ UserSchema createLinkedSchema(User user, Container container, String name, Strin */ List getSharedCustomViews(@NotNull User user, Container container, @Nullable String schemaName, @Nullable String queryName, boolean includeInherited); + @Deprecated // Use the three parameter version of the function to get views in product containers + List getDatabaseCustomViews(@NotNull User user, Container container, @Nullable User owner, @Nullable String schemaName, @Nullable String queryName, boolean includeInherited, boolean sharedOnly); + /** * Returns custom views stored in the database (not module custom views) that meet the criteria. This is not appropriate * for UI operations (see getCustomViews() for that), but it's important for query change listeners. See #21641 and #21862. */ - List getDatabaseCustomViews(@NotNull User user, Container container, @Nullable User owner, @Nullable String schemaName, @Nullable String queryName, boolean includeInherited, boolean sharedOnly); + List getDatabaseCustomViews(@NotNull Container container, @Nullable String schemaName, @Nullable String queryName); int importCustomViews(User user, Container container, VirtualFile viewDir) throws IOException; diff --git a/query/src/org/labkey/query/CustomViewQueryChangeListener.java b/query/src/org/labkey/query/CustomViewQueryChangeListener.java index ff9cc681eb1..9e04d082f07 100644 --- a/query/src/org/labkey/query/CustomViewQueryChangeListener.java +++ b/query/src/org/labkey/query/CustomViewQueryChangeListener.java @@ -63,20 +63,20 @@ public void queryChanged(User user, Container container, ContainerFilter scope, { if (property.equals(QueryProperty.Name)) { - _updateCustomViewQueryNameChange(user, container, schema, changes); + _updateCustomViewQueryNameChange(container, schema, changes); } if (property.equals(QueryProperty.SchemaName)) { - _updateCustomViewSchemaNameChange(user, container, changes); + _updateCustomViewSchemaNameChange(container, changes); } if (property.equals(QueryProperty.ColumnType)) { - _updateCustomViewColumnTypeChange(user, container, schema, changes); + _updateCustomViewColumnTypeChange(container, schema, changes); } } - private void _updateCustomViewColumnTypeChange(User user, Container container, SchemaKey schema, @NotNull Collection> changes) + private void _updateCustomViewColumnTypeChange(Container container, SchemaKey schema, @NotNull Collection> changes) { for (QueryPropertyChange qpc : changes) { @@ -93,7 +93,7 @@ private void _updateCustomViewColumnTypeChange(User user, Container container, S String columnName = newDp.getName() == null ? oldDp.getName() : newDp.getName(); - List databaseCustomViews = QueryService.get().getDatabaseCustomViews(user, container, null, schema.toString(), queryName, false, false); + List databaseCustomViews = QueryService.get().getDatabaseCustomViews(container, schema.toString(), queryName); for (CustomView customView : databaseCustomViews) { @@ -221,7 +221,7 @@ private String dependentViewMessage(Container container, CustomView view) return sb.toString(); } - private void _updateCustomViewQueryNameChange(User user, Container container, SchemaKey schemaKey, Collection> changes) + private void _updateCustomViewQueryNameChange(Container container, SchemaKey schemaKey, Collection> changes) { // most property updates only care about the query name old value string and new value string Map queryNameChangeMap = new CaseInsensitiveHashMap<>(); @@ -230,7 +230,7 @@ private void _updateCustomViewQueryNameChange(User user, Container container, Sc queryNameChangeMap.put((String)qpc.getOldValue(), (String)qpc.getNewValue()); } - List databaseCustomViews = QueryService.get().getDatabaseCustomViews(user, container, null, schemaKey.toString(), null, false, false); + List databaseCustomViews = QueryService.get().getDatabaseCustomViews(container, schemaKey.toString(), null); for (CustomView customView : databaseCustomViews) { @@ -262,7 +262,7 @@ private void _updateCustomViewQueryNameChange(User user, Container container, Sc } } - private void _updateCustomViewSchemaNameChange(User user, Container container, Collection> changes) + private void _updateCustomViewSchemaNameChange(Container container, Collection> changes) { Map schemaNameChangeMap = new CaseInsensitiveHashMap<>(); for (QueryPropertyChange qpc : changes) @@ -279,7 +279,7 @@ private void _updateCustomViewSchemaNameChange(User user, Container container, C { String newSchema = schemaNameChangeMap.get(oldSchema); - List databaseCustomViews = QueryService.get().getDatabaseCustomViews(user, container, null, oldSchema, null, false, false); + List databaseCustomViews = QueryService.get().getDatabaseCustomViews(container, oldSchema, null); for (CustomView customView : databaseCustomViews) { diff --git a/query/src/org/labkey/query/QueryServiceImpl.java b/query/src/org/labkey/query/QueryServiceImpl.java index beca1695766..95b68d7e1ec 100644 --- a/query/src/org/labkey/query/QueryServiceImpl.java +++ b/query/src/org/labkey/query/QueryServiceImpl.java @@ -1296,6 +1296,7 @@ private List _getCustomViews(final @NotNull User user, final Contain return new ArrayList<>(views); } + @Deprecated @Override public List getDatabaseCustomViews(@NotNull User user, Container container, @Nullable User owner, @Nullable String schemaName, @Nullable String queryName, boolean includeInherited, boolean sharedOnly) { @@ -1336,6 +1337,73 @@ public List getDatabaseCustomViews(@NotNull User user, Container con return allViews.stream().filter(view -> !(view instanceof ModuleCustomView)).collect(Collectors.toList()); } + @Override + public List getDatabaseCustomViews(@NotNull Container container, @Nullable String schemaName, @Nullable String queryName) + { + User searchUser = User.getSearchUser(); + // GitHub Issue 1058: Sample Finder saved views in subfolder break after MVTC to TC conversion + Collection containerIds = container.getProductFoldersDataContainerFilter(searchUser).getIds(); + + SimpleFilter filter = new SimpleFilter(); + if (containerIds != null) + filter.addInClause(FieldKey.fromParts("Container"), containerIds); + else + filter = SimpleFilter.createContainerFilter(container, "Container"); + + if (schemaName != null) + filter.addCondition(FieldKey.fromParts("Schema"), schemaName); + if (queryName != null) + filter.addCondition(FieldKey.fromParts("QueryName"), queryName); + + List cstmViews = new TableSelector(QueryManager.get().getTableInfoCustomView(), filter, null).getArrayList(CstmView.class); + + List result = new ArrayList<>(); + + Map> containerViews = new HashMap<>(); + for (CstmView cstmView : cstmViews) + { + Container viewContainer = cstmView.lookupContainer(); + if (viewContainer != null) + containerViews.computeIfAbsent(viewContainer, k -> new ArrayList<>()).add(cstmView); + } + + for (Map.Entry> containerCstmViews: containerViews.entrySet()) + { + Map schemas = new HashMap<>(); + Map, QueryDefinition> queryDefs = new HashMap<>(); + Container viewContainer = containerCstmViews.getKey(); + List views = containerCstmViews.getValue(); + + for (CstmView cstmView : views) + { + Pair key = new Pair<>(cstmView.getSchema(), cstmView.getQueryName()); + QueryDefinition queryDef = queryDefs.get(key); + if (queryDef == null) + { + UserSchema schema = schemas.get(cstmView.getSchema()); + if (schema == null) + { + schema = getUserSchema(searchUser, viewContainer, cstmView.getSchema()); + schemas.put(cstmView.getSchema(), schema); + } + if (schema != null) + { + queryDef = schema.getQueryDefForTable(cstmView.getQueryName()); + queryDefs.put(key, queryDef); + } + } + + if (queryDef != null) + { + result.add(new CustomViewImpl(queryDef, cstmView)); + } + } + } + + return result; + } + + @Override public List getFileBasedCustomViews(Container container, QueryDefinition qd, Path path, String query, Module... extraModules) {