Repository navigation
fix(search): keep trashed and live folders at the same path apart - #3602
Conversation
A trashed folder keeps its path in the index, so a new folder can take the same one. The descendant lookup behind move, delete, restore and purge matched on space and path only: purging the trashed folder took the live folder and its descendants out of the index, and moving the live folder carried the trashed tree along. Both engines now also match the root's trash state; purge with onlyDeleted keeps matching the trashed ones only.
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
🟢 Coverage 74.42% diff coverage · +0.01% coverage variation
Metric Results Coverage variation ✅ +0.01% coverage variation (-1.00%) Diff coverage ✅ 74.42% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (74462d3) 89037 21582 24.24% Head commit (b1efb8c) 89056 (+19) 21599 (+17) 24.25% (+0.01%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#3602) 43 32 74.42% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
dschmidt
left a comment
There was a problem hiding this comment.
Instead of adding the deleted / onlyDeleted bools to forEachResourceByPath and forSelfAndDescendants, should the caller pass the query into forEachResourceByPath? It would then only do the paging, and each caller adds the Deleted filter it needs.
Roughly, with three small new helpers:
treeQuery(root): the RootID + Path conjunction thatforEachResourceByPathbuilds inline todaydeletedQuery(deleted): theDeletedbool field queryb.pushing(fn): the currentapplyclosure fromforSelfAndDescendants, pulled out soPurgecan use it too
// forSelfAndDescendants(id, fn): back to the signature from main
q := treeQuery(root)
q.AddQuery(deletedQuery(root.Deleted))
forEachResourceByPath(q, b.index, fn)
// Purge(id, true): doesn't go through forSelfAndDescendants
q := treeQuery(root)
q.AddQuery(deletedQuery(true)) // also leaves out the live root, since the Path term matches the folder itself
forEachResourceByPath(q, b.index, b.pushing(purge))In forSelfAndDescendants the query has to be built before fn(root) runs, just like rootPath today.
Personally I really dislike boolean parameters as I think it's really hard to reason about what they are doing
Instead of deleted/onlyDeleted bool parameters, the caller now builds the query and forEachMatch only does the paging.
dschmidt
left a comment
There was a problem hiding this comment.
great, looks much better to me now 👍
|
@dschmidt 👍 I hear you about the bool parameter. I wasn't comfortable with the idea of a thanks for the review! |
|
Sounds very good, thanks for taking my review into account 🙂 |
|
I think we need port it to stable because this case especially bad for opensearch steps:
Actual: 7.2.4 - search result is empty. dev (main branch) - alan can see folder and file |
#1949) ##### [\`8.1.0\`](https://github.com/opencloud-eu/opencloud/blob/HEAD/CHANGELOG.md#810---2026-10-05) ##### ❤️ Thanks to all contributors! ❤️ [@NickWalters](https://github.com/NickWalters), [@aduffeck](https://github.com/aduffeck), [@butonic](https://github.com/butonic), [@dschmidt](https://github.com/dschmidt), [@fschade](https://github.com/fschade), [@maki5](https://github.com/maki5), [@micbar](https://github.com/micbar), [@pascalwengerter](https://github.com/pascalwengerter), [@pbleser-oc](https://github.com/pbleser-oc), [@rhafer](https://github.com/rhafer), [@saw-jan](https://github.com/saw-jan), [@schweigisito](https://github.com/schweigisito), [@v-scharf](https://github.com/v-scharf), [@zerox80](https://github.com/zerox80) ##### 🔒 Security - feat(proxy): add optional OIDC access token audience validation \[[#3466](opencloud-eu/opencloud#3466)] ##### 🐛 Bug Fixes - Reindex disabled spaces once they get enabled again \[[#3579](opencloud-eu/opencloud#3579)] - fix(search): tika key fixes \[[#3651](opencloud-eu/opencloud#3651)] - fix(search): keep trashed and live folders at the same path apart \[[#3602](opencloud-eu/opencloud#3602)] - Fix/uploads cli no async consumer \[[#3603](opencloud-eu/opencloud#3603)] - Remove the timeout when reindexing spaces \[[#3543](opencloud-eu/opencloud#3543)] - fix(shares): not auto accepting shares created by guest users \[[#3533](opencloud-eu/opencloud#3533)] - fix(graph): fix PatchMe method to prevent password change \[[#3526](opencloud-eu/opencloud#3526)] ##### 📈 Enhancement - feat: add new editor roles \[[#3637](opencloud-eu/opencloud#3637)] - feat(collaboration): let admins disable wopi extensions \[[#3633](opencloud-eu/opencloud#3633)] - fix(collaboration): send LastModifiedTime and the EuroOffice file size \[[#3636](opencloud-eu/opencloud#3636)] - feat(collaboration): mobile web view for EuroOffice \[[#3635](opencloud-eu/opencloud#3635)] - fix(collaboration): harden wopi token handling \[[#3630](opencloud-eu/opencloud#3630)] - add posixfs index command \[[#3068](opencloud-eu/opencloud#3068)] - feat(proxy): add per-service metrics to the proxy service \[[#3521](opencloud-eu/opencloud#3521)] ##### ✅ Tests - fix(search): ellipsize parity matrix labels by runes, not bytes \[[#3643](opencloud-eu/opencloud#3643)] - fix(collaboration): mint the mobile view test token with the token manager secret \[[#3647](opencloud-eu/opencloud#3647)] - run cli tests with decomposed nightly \[[#3580](opencloud-eu/opencloud#3580)] - \[decomposed] test(api): remove passing notification tests from expected failure \[[#3555](opencloud-eu/opencloud#3555)] - api-test: add CLI test for reindexing all spaces including disabled \[[#3560](opencloud-eu/opencloud#3560)] ##### 📚 Documentation - \[SKIP CI] fix: add file_read documentation to audit log docu \[[#3503](opencloud-eu/opencloud#3503)] ##### 📦️ Dependencies - \[full-ci] chore: bump web to v8.1.0 \[[#3656](opencloud-eu/opencloud#3656)] - chore: bump reva to latest main \[[#3642](opencloud-eu/opencloud#3642)] - chore: bump libre-graph-api-go to v1.0.8 \[[#3645](opencloud-eu/opencloud#3645)] - build(deps): bump github.com/nats-io/nats.go from 1.53.1 to 1.54.0 \[[#3584](opencloud-eu/opencloud#3584)] - build(deps): bump github.com/onsi/gomega from 1.42.1 to 1.43.1 \[[#3582](opencloud-eu/opencloud#3582)] - build(deps): bump google.golang.org/grpc from 1.83.2 to 1.84.0 \[[#3581](opencloud-eu/opencloud#3581)] - build(deps): bump github.com/beevik/etree from 1.7.1 to 1.8.0 \[[#3583](opencloud-eu/opencloud#3583)] - build(deps): bump golang.org/x/image from 0.45.0 to 0.46.0 \[[#3573](opencloud-eu/opencloud#3573)] - build(deps): bump github.com/nats-io/nats-server/v2 from 2.14.5 to 2.15.0 \[[#3576](opencloud-eu/opencloud#3576)] - build(deps): bump golang.org/x/text from 0.41.0 to 0.42.0 \[[#3552](opencloud-eu/opencloud#3552)] - build(deps): bump golang.org/x/sync from 0.22.0 to 0.23.0 \[[#3551](opencloud-eu/opencloud#3551)] - build(deps): bump go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc from 0.70.0 to 0.71.0 \[[#3427](opencloud-eu/opencloud#3427)] - build(deps): bump github.com/olekukonko/errors from 1.2.0 to 1.3.0 \[[#3557](opencloud-eu/opencloud#3557)] - build(deps): bump github.com/prometheus/client_model from 0.6.2 to 0.6.3 \[[#3550](opencloud-eu/opencloud#3550)] - build(deps): bump github.com/shamaton/msgpack/v2 from 2.4.1 to 2.4.2 \[[#3459](opencloud-eu/opencloud#3459)] - build(deps): bump go.opentelemetry.io/otel/exporters/stdout/stdouttrace from 1.45.0 to 1.46.0 \[[#3428](opencloud-eu/opencloud#3428)] - build(deps): bump github.com/sirupsen/logrus from 1.10.1 to 1.10.2 \[[#3492](opencloud-eu/opencloud#3492)] Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
A trashed folder keeps its path in the index, so a live folder can take the same path. Move/delete/restore/purge looked up descendants by path only. As a result, purging the trashed
./aremoved the live./atree, and moving the live./atook the trashed tree with it. Both engines now also match the root's trash state.