Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix populate depth and infinite recursion for Collection Links #1459

Open
wants to merge 2 commits into
base: next
Choose a base branch
from

Conversation

beasteers
Copy link

Fixes: #1450

What is this about?

When using ?populate=1, ?populate=2, etc. when querying a collection with collectionlink fields, the populate query value also doubles as a max depth parameter. However, the index is off by 1, meaning that ?populate=1 will populate 2 depths and ?populate=0 will not populate anything meaning that it is currently impossible to populate only a depth of 1.

The issue is most apparent when you have a cyclical relationship between two collections. When you enable populate, it will automatically fill A->B->A instead of just A->B

Before

  • ?populate=0 gives: {"a": {link}}
  • not possible: {"a": {"b": {link}}}
  • ?populate=1 gives: {"a": {"b": {"a": {link}}}}

After

  • ?populate=0 gives: {"a": {link}}
  • ?populate=1 gives: {"a": {"b": {link}}}
  • ?populate=2 gives: {"a": {"b": {"a": {link}}}}

What this PR does:

It updates the logic of the populate function so that the value that the user passes actually aligns with the depth that they want to populate

Additionally, this also fixes infinite recursion for cyclical collections when ?populate=-1 by tracking the _id and collection values when populating.

Example Outputs using this PR:

Relationships:

  • a1 -> b1 -> a1
  • a2 -> b1 -> a1
// /api/collections/get/A?populate=0
{
    "entries": [
        {
            "name": "a1",
            "b": {"_id": "60ff73c9da60345fd133d081", "link": "B"},
            "_id": "60ff73aeadc8f87a9f76d611"
        },
        {
            "name": "a2",
            "b": {"_id": "60ff73c9da60345fd133d081", "link": "B"},
            "_id": "60fffe418c5238608847fc93"
        }
    ]
}
// /api/collections/get/A?populate=1
{
    "entries": [
        {
            "name": "a1",
            "b": {
                "name": "b1",
                "a": {"_id": "60ff73aeadc8f87a9f76d611", "link": "A"},
                "_id": "60ff73c9da60345fd133d081",
                "_link": "B"
            },
            "_id": "60ff73aeadc8f87a9f76d611"
        },
        {
            "name": "a2",
            "b": {
                "name": "b1",
                "a": {"_id": "60ff73aeadc8f87a9f76d611", "link": "A"},
                "_id": "60ff73c9da60345fd133d081",
                "_link": "B"
            },
            "_id": "60fffe418c5238608847fc93"
        }
    ]
}
// /api/collections/get/A?populate=2
// /api/collections/get/A?populate=3
// /api/collections/get/A?populate=4   (etc.)
// /api/collections/get/A?populate=-1
{
    "entries": [
        {
            "name": "a1",
            "b": {
                "name": "b1",
                "a": {
                    "_id": "60ff73aeadc8f87a9f76d611",
                    "link": "A"
                },
                "_id": "60ff73c9da60345fd133d081",
                "_link": "B"
            },
            "_created": 1627354030,
            "_id": "60ff73aeadc8f87a9f76d611"
        },
        {
            "name": "a2",
            "b": {
                "name": "b1",
                "a": {
                    "name": "a1",
                    "b": {
                        "_id": "60ff73c9da60345fd133d081",
                        "link": "B"
                    },
                    "_id": "60ff73aeadc8f87a9f76d611",
                    "_link": "A"
                },
                "_id": "60ff73c9da60345fd133d081",
                "_link": "B"
            },
            "_id": "60fffe418c5238608847fc93"
        }
    ],
}

Example Setup

Setup collections:

// POST /api/collections/createCollection
{
    "name": "A",
    "data": {
        "fields": [
            {"name": "name", "type": "text"},
            {"name": "b", "type": "collectionlink", "options": {"link": "B"}}
        ]
    }
}
// POST /api/collections/createCollection
{
    "name": "B",
    "data": {
        "fields": [
            {"name": "name", "type": "text"},
            {"name": "a", "type": "collectionlink", "options": {"link": "A"}}
        ]
    }
}

Setup entries:

// POST /api/collections/save/A
{ "data": [{"name": "a1"}, {"name": "a2"}] }
// get _id as _id_a1, _id_a2
// POST /api/collections/save/B
{ "data": [{"name": "b1"}, {"name": "b2"}] }
// get _id as _id_b1, _id_b2

// POST /api/collections/save/A
{ "data": [{"_id": _id_a1, "b": {"_id": _id_b1, "link": "B"}}, {"_id": _id_a2, "b": {"_id": _id_b1, "link": "B"}}] }

// POST /api/collections/save/B
{ "data": [{"_id": _id_b1, "a": {"_id": _id_a1, "link": "A"}, "b": null}, {"_id": _id_b2, "a": {"_id": _id_a1, "link": "A"}, "b": null}] }

sample docker-compose.yml

version: '2.4'

services:
  cockpit:
    container_name: cockpit
    build:
      context: "./"
    image: cockpit:dev
    volumes:
      - "./:/var/www/html"
    ports:
     - "8010:80"
    environment: {}
    restart: always

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

collection query populate depth is off by 1
1 participant