From 61a30e018736c77c0b815f5c4315f7773c824804 Mon Sep 17 00:00:00 2001 From: David Vogt Date: Tue, 4 Jun 2024 14:35:24 +0200 Subject: [PATCH] refactor: drop django-mptt in favour of django-tree-queries Django-Tree-Queries works with recursive CTEs (common table expressions) to deal with hierarchical relationships, generally achieving the same result, but without the `right`, `left` and `tree_id` fields. Django-MPTT has been unmaintained for several years, and we're suspecting some subtle bugs in it that we can't really reproduce or verify right now. Anyway it's a good time to get rid of it. Note: Some old migrations needed to be changed, as we cannot refer to MPTT fields anymore. They were essentially regular foreign keys however, so this won't break the database. BREAKING! This breaks if Emeis is used as a Django app directly, and depends on any of the MPTT API / features. --- .../core/management/commands/create_scope.py | 2 - emeis/core/migrations/0001_initial.py | 3 +- .../migrations/0009_alter_scope_parent.py | 5 +- emeis/core/migrations/0010_scope_full_name.py | 2 +- .../migrations/0011_mptt_to_tree_queries.py | 45 ++ emeis/core/models.py | 21 +- emeis/core/serializers.py | 25 +- emeis/core/tests/snapshots/snap_test_api.py | 545 ++++++++++++++++-- emeis/core/tests/test_api.py | 11 +- emeis/core/tests/test_create_scope_command.py | 16 +- emeis/core/tests/test_models.py | 8 +- emeis/core/tests/test_prefetch_visibility.py | 2 +- emeis/core/tests/test_views.py | 12 +- emeis/core/utils.py | 15 - emeis/core/views.py | 13 +- emeis/settings.py | 1 - requirements-base.txt | 3 +- setup.py | 2 +- 18 files changed, 634 insertions(+), 97 deletions(-) create mode 100644 emeis/core/migrations/0011_mptt_to_tree_queries.py diff --git a/emeis/core/management/commands/create_scope.py b/emeis/core/management/commands/create_scope.py index 5d3faee3..91cf5b0b 100644 --- a/emeis/core/management/commands/create_scope.py +++ b/emeis/core/management/commands/create_scope.py @@ -3,7 +3,6 @@ from django.core.management.base import BaseCommand from emeis.core.models import ACL, Role, Scope, User -from emeis.core.utils import rebuild_mptt_model class Command(BaseCommand): @@ -78,7 +77,6 @@ def handle(self, *args, **options): options["name"] = json.loads(options["name"]) new_scope = Scope.objects.create(name=options["name"], parent=parent) - rebuild_mptt_model(Scope) out_info["scope_id"] = str(new_scope.pk) if options["user"]: diff --git a/emeis/core/migrations/0001_initial.py b/emeis/core/migrations/0001_initial.py index 7ca8db8a..1a9dabd6 100644 --- a/emeis/core/migrations/0001_initial.py +++ b/emeis/core/migrations/0001_initial.py @@ -6,7 +6,6 @@ import django.utils.timezone import localized_fields.fields.char_field import localized_fields.fields.text_field -import mptt.fields from django.conf import settings from django.db import migrations, models @@ -224,7 +223,7 @@ class Migration(migrations.Migration): ), ( "parent", - mptt.fields.TreeForeignKey( + models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, diff --git a/emeis/core/migrations/0009_alter_scope_parent.py b/emeis/core/migrations/0009_alter_scope_parent.py index 60317221..f12f9a3c 100644 --- a/emeis/core/migrations/0009_alter_scope_parent.py +++ b/emeis/core/migrations/0009_alter_scope_parent.py @@ -1,8 +1,7 @@ # Generated by Django 3.2.12 on 2022-04-21 07:24 -from django.db import migrations import django.db.models.deletion -import mptt.fields +from django.db import migrations, models class Migration(migrations.Migration): @@ -14,7 +13,7 @@ class Migration(migrations.Migration): migrations.AlterField( model_name="scope", name="parent", - field=mptt.fields.TreeForeignKey( + field=models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, diff --git a/emeis/core/migrations/0010_scope_full_name.py b/emeis/core/migrations/0010_scope_full_name.py index 620a85fd..f1291048 100644 --- a/emeis/core/migrations/0010_scope_full_name.py +++ b/emeis/core/migrations/0010_scope_full_name.py @@ -1,7 +1,7 @@ # Generated by Django 3.2.15 on 2022-09-23 09:13 -from django.db import migrations import localized_fields.fields.char_field +from django.db import migrations from emeis.core import models diff --git a/emeis/core/migrations/0011_mptt_to_tree_queries.py b/emeis/core/migrations/0011_mptt_to_tree_queries.py new file mode 100644 index 00000000..87403182 --- /dev/null +++ b/emeis/core/migrations/0011_mptt_to_tree_queries.py @@ -0,0 +1,45 @@ +# Generated by Django 3.2.25 on 2024-06-03 14:17 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("emeis_core", "0010_scope_full_name"), + ] + + operations = [ + migrations.AlterModelOptions( + name="scope", + options={"ordering": ["full_name"]}, + ), + migrations.RemoveField( + model_name="scope", + name="level", + ), + migrations.RemoveField( + model_name="scope", + name="lft", + ), + migrations.RemoveField( + model_name="scope", + name="rght", + ), + migrations.RemoveField( + model_name="scope", + name="tree_id", + ), + migrations.AlterField( + model_name="scope", + name="parent", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="children", + to="emeis_core.scope", + verbose_name="parent", + ), + ), + ] diff --git a/emeis/core/models.py b/emeis/core/models.py index 10e4ca69..00360be9 100644 --- a/emeis/core/models.py +++ b/emeis/core/models.py @@ -10,7 +10,7 @@ from django.utils import timezone, translation from django.utils.translation import gettext_lazy as _ from localized_fields.fields import LocalizedCharField, LocalizedTextField -from mptt.models import MPTTModel, TreeForeignKey +from tree_queries.models import TreeNode, TreeQuerySet def make_uuid(): @@ -158,7 +158,7 @@ def is_authenticated(self): return True -class Scope(MPTTModel, UUIDModel): +class Scope(TreeNode, UUIDModel): name = LocalizedCharField(_("scope name"), blank=False, null=False, required=False) full_name = LocalizedCharField( @@ -168,20 +168,21 @@ class Scope(MPTTModel, UUIDModel): description = LocalizedTextField( _("scope description"), null=True, blank=True, required=False ) - parent = TreeForeignKey( - "self", - on_delete=models.CASCADE, - null=True, - blank=True, - related_name="children", - ) is_active = models.BooleanField(default=True) + objects = TreeQuerySet.as_manager(with_tree_fields=True) + + def save(self, *args, **kwargs): + # django-tree-queries does validation in TreeNode.clean(), which is not + # called by DRF (only by django forms), so we have to do this here + self.clean() + return super().save(*args, **kwargs) + def __str__(self): return f"{type(self).__name__} ({self.full_name}, pk={self.pk})" class Meta: - ordering = ["full_name"] + ordering = ["name"] @receiver(pre_save, sender=Scope) diff --git a/emeis/core/serializers.py b/emeis/core/serializers.py index 7f2db8a1..288c5752 100644 --- a/emeis/core/serializers.py +++ b/emeis/core/serializers.py @@ -33,6 +33,10 @@ class Meta: class MyACLSerializer(BaseSerializer): + scope = serializers.ResourceRelatedField( + queryset=Scope.objects.all(), required=False, many=False + ) + included_serializers = { "scope": "emeis.core.serializers.ScopeSerializer", "role": "emeis.core.serializers.RoleSerializer", @@ -73,6 +77,22 @@ class Meta: class ScopeSerializer(BaseSerializer): + level = serializers.SerializerMethodField() + + def get_level(self, obj): + depth = getattr(obj, "tree_depth", None) + if depth is not None: + return depth + + # Note: This should only happen on CREATE, never in GET (Either list, + # detail, or include!) In CREATE, it's a new object that doesn't come + # from a QS + + # Sometimes, the model object may come out of a non-django-tree-queries + # QS, and thus would not have the `tree_*` attributes amended. Then we + # need to go the "slow path" + return obj.ancestors().count() + class Meta: model = Scope fields = BaseSerializer.Meta.fields + ( @@ -83,7 +103,7 @@ class Meta: "full_name", "is_active", ) - read_only_fields = ["full_name"] + read_only_fields = ["full_name", "level"] class PermissionSerializer(BaseSerializer): @@ -111,6 +131,9 @@ class Meta: class ACLSerializer(BaseSerializer): + scope = serializers.ResourceRelatedField( + queryset=Scope.objects.all(), required=False, many=False + ) included_serializers = { "user": UserSerializer, "scope": ScopeSerializer, diff --git a/emeis/core/tests/snapshots/snap_test_api.py b/emeis/core/tests/snapshots/snap_test_api.py index c69bebc3..42a5bdf3 100644 --- a/emeis/core/tests/snapshots/snap_test_api.py +++ b/emeis/core/tests/snapshots/snap_test_api.py @@ -9,8 +9,44 @@ snapshots["test_api_create[ACLViewSet] 1"] = { "queries": [ + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" = \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC LIMIT 21""", 'SELECT "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined" FROM "emeis_core_user" WHERE "emeis_core_user"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', - 'SELECT "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level" FROM "emeis_core_scope" WHERE "emeis_core_scope"."id" = \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid LIMIT 21', 'SELECT "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_role" WHERE "emeis_core_role"."slug" = \'fund-executive-most\' LIMIT 21', 'SELECT (1) AS "a" FROM "emeis_core_acl" WHERE ("emeis_core_acl"."role_id" = \'fund-executive-most\' AND "emeis_core_acl"."scope_id" = \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid AND "emeis_core_acl"."user_id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid) LIMIT 1', 'INSERT INTO "emeis_core_acl" ("created_at", "modified_at", "created_by_user_id", "metainfo", "id", "user_id", "scope_id", "role_id") VALUES (\'2017-05-21T00:00:00+00:00\'::timestamptz, \'2017-05-21T00:00:00+00:00\'::timestamptz, \'ea416ed0-759d-46a8-de58-f63a59077499\'::uuid, \'{}\', \'fb0e22c7-9ac7-5679-e988-1e6ba183b354\'::uuid, \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid, \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid, \'fund-executive-most\')', @@ -154,10 +190,82 @@ snapshots["test_api_create[ScopeViewSet] 1"] = { "queries": [ - 'SELECT MAX("emeis_core_scope"."tree_id") AS "tree_id__max" FROM "emeis_core_scope"', - 'SELECT "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level" FROM "emeis_core_scope" WHERE "emeis_core_scope"."parent_id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid ORDER BY "emeis_core_scope"."tree_id" ASC, "emeis_core_scope"."lft" ASC', - """INSERT INTO "emeis_core_scope" ("created_at", "modified_at", "created_by_user_id", "metainfo", "id", "name", "full_name", "description", "parent_id", "is_active", "lft", "rght", "tree_id", "level") VALUES (\'2017-05-21T00:00:00+00:00\'::timestamptz, \'2017-05-21T00:00:00+00:00\'::timestamptz, \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid, \'{}\', \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid, hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Pamela Horton\',\'\',\'\']), hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Pamela Horton\',\'Pamela Horton\',\'Pamela Horton\']), hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Effort meet relationship far. Option program interesting station. First where during teach country talk across. -Argue move appear catch toward help wind. Material minute ago get.','','']), NULL, true, 1, 2, 1, 0)""", + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."parent_id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC""", + """INSERT INTO "emeis_core_scope" ("parent_id", "created_at", "modified_at", "created_by_user_id", "metainfo", "id", "name", "full_name", "description", "is_active") VALUES (NULL, \'2017-05-21T00:00:00+00:00\'::timestamptz, \'2017-05-21T00:00:00+00:00\'::timestamptz, \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid, \'{}\', \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid, hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Pamela Horton\',\'\',\'\']), hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Pamela Horton\',\'Pamela Horton\',\'Pamela Horton\']), hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Effort meet relationship far. Option program interesting station. First where during teach country talk across. +Argue move appear catch toward help wind. Material minute ago get.','','']), true)""", + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC LIMIT 21""", ], "request": { "CONTENT_LENGTH": "614", @@ -254,7 +362,44 @@ snapshots["test_api_destroy[ACLViewSet] 1"] = { "queries": [ - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid LIMIT 21', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid LIMIT 21', + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" IN (\'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid) AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC""", 'DELETE FROM "emeis_core_acl" WHERE "emeis_core_acl"."id" IN (\'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid)', ], "request": { @@ -285,7 +430,7 @@ snapshots["test_api_destroy[RoleViewSet] 1"] = { "queries": [ 'SELECT "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_role" WHERE "emeis_core_role"."slug" = \'note-act-source\' LIMIT 21', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") WHERE "emeis_core_acl"."role_id" IN (\'note-act-source\')', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") WHERE "emeis_core_acl"."role_id" IN (\'note-act-source\')', 'DELETE FROM "emeis_core_role_permissions" WHERE "emeis_core_role_permissions"."role_id" IN (\'note-act-source\')', 'DELETE FROM "emeis_core_acl" WHERE "emeis_core_acl"."role_id" IN (\'note-act-source\')', 'DELETE FROM "emeis_core_role" WHERE "emeis_core_role"."slug" IN (\'note-act-source\')', @@ -301,22 +446,45 @@ snapshots["test_api_destroy[ScopeViewSet] 1"] = { "queries": [ - 'SELECT "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level" FROM "emeis_core_scope" WHERE "emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', - 'SELECT "emeis_core_scope"."id", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id" FROM "emeis_core_scope" WHERE "emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', """ - UPDATE "emeis_core_scope" - SET "lft" = CASE - WHEN "lft" > 2 - THEN "lft" + -2 - ELSE "lft" END, - "rght" = CASE - WHEN "rght" > 2 - THEN "rght" + -2 - ELSE "rght" END - WHERE "tree_id" = 1 - AND ("lft" > 2 OR "rght" > 2)""", - 'SELECT "emeis_core_scope"."id" FROM "emeis_core_scope" WHERE "emeis_core_scope"."parent_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid) ORDER BY "emeis_core_scope"."full_name" ASC', + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY ("emeis_core_scope"."name" -> \'en\') ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC LIMIT 21""", + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', + 'SELECT "emeis_core_scope"."id" FROM "emeis_core_scope" WHERE "emeis_core_scope"."parent_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid) ORDER BY "emeis_core_scope"."name" ASC', 'DELETE FROM "emeis_core_acl" WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', 'DELETE FROM "emeis_core_scope" WHERE "emeis_core_scope"."id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', ], @@ -332,9 +500,9 @@ snapshots["test_api_destroy[UserViewSet] 1"] = { "queries": [ 'SELECT "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined" FROM "emeis_core_user" WHERE "emeis_core_user"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', 'SELECT "emeis_core_user"."id" FROM "emeis_core_user" WHERE "emeis_core_user"."created_by_user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', - 'SELECT "emeis_core_scope"."id" FROM "emeis_core_scope" WHERE "emeis_core_scope"."created_by_user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid) ORDER BY "emeis_core_scope"."full_name" ASC', + 'SELECT "emeis_core_scope"."id" FROM "emeis_core_scope" WHERE "emeis_core_scope"."created_by_user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid) ORDER BY "emeis_core_scope"."name" ASC', 'SELECT "emeis_core_role"."slug" FROM "emeis_core_role" WHERE "emeis_core_role"."created_by_user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid) ORDER BY "emeis_core_role"."slug" ASC', 'SELECT "emeis_core_permission"."slug" FROM "emeis_core_permission" WHERE "emeis_core_permission"."created_by_user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id" FROM "emeis_core_acl" WHERE "emeis_core_acl"."created_by_user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', @@ -352,7 +520,44 @@ snapshots["test_api_detail[ACLViewSet] 1"] = { "queries": [ - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid LIMIT 21', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid LIMIT 21', + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" IN (\'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid) AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC""", 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id" FROM "emeis_core_acl" WHERE "emeis_core_acl"."user_id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid', 'SELECT "emeis_core_permission"."created_at", "emeis_core_permission"."modified_at", "emeis_core_permission"."created_by_user_id", "emeis_core_permission"."metainfo", "emeis_core_permission"."slug", "emeis_core_permission"."name", "emeis_core_permission"."description" FROM "emeis_core_permission" INNER JOIN "emeis_core_role_permissions" ON ("emeis_core_permission"."slug" = "emeis_core_role_permissions"."permission_id") WHERE "emeis_core_role_permissions"."role_id" = \'fund-executive-most\'', ], @@ -516,7 +721,7 @@ "queries": [ 'SELECT "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_role" WHERE "emeis_core_role"."slug" = \'note-act-source\' LIMIT 21', 'SELECT ("emeis_core_role_permissions"."role_id") AS "_prefetch_related_val_role_id", "emeis_core_permission"."created_at", "emeis_core_permission"."modified_at", "emeis_core_permission"."created_by_user_id", "emeis_core_permission"."metainfo", "emeis_core_permission"."slug", "emeis_core_permission"."name", "emeis_core_permission"."description" FROM "emeis_core_permission" INNER JOIN "emeis_core_role_permissions" ON ("emeis_core_permission"."slug" = "emeis_core_role_permissions"."permission_id") WHERE "emeis_core_role_permissions"."role_id" IN (\'note-act-source\')', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") WHERE "emeis_core_acl"."role_id" IN (\'note-act-source\')', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") WHERE "emeis_core_acl"."role_id" IN (\'note-act-source\')', ], "request": { "CONTENT_TYPE": "application/octet-stream", @@ -553,8 +758,44 @@ snapshots["test_api_detail[ScopeViewSet] 1"] = { "queries": [ - 'SELECT "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level" FROM "emeis_core_scope" WHERE "emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY ("emeis_core_scope"."name" -> \'en\') ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC LIMIT 21""", + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', ], "request": { "CONTENT_TYPE": "application/octet-stream", @@ -598,7 +839,7 @@ snapshots["test_api_detail[UserViewSet] 1"] = { "queries": [ 'SELECT "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined" FROM "emeis_core_user" WHERE "emeis_core_user"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', ], "request": { "CONTENT_TYPE": "application/octet-stream", @@ -638,7 +879,44 @@ snapshots["test_api_list[ACLViewSet] 1"] = { "queries": [ - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug")', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug")', + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" IN (\'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid, \'dad3a37a-a9d5-0688-b515-7698acfd7aee\'::uuid, \'aba369f7-d2b2-8a90-98a0-a26feb7dc965\'::uuid) AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC""", 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id" FROM "emeis_core_acl" WHERE "emeis_core_acl"."user_id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid', 'SELECT "emeis_core_permission"."created_at", "emeis_core_permission"."modified_at", "emeis_core_permission"."created_by_user_id", "emeis_core_permission"."metainfo", "emeis_core_permission"."slug", "emeis_core_permission"."name", "emeis_core_permission"."description" FROM "emeis_core_permission" INNER JOIN "emeis_core_role_permissions" ON ("emeis_core_permission"."slug" = "emeis_core_role_permissions"."permission_id") WHERE "emeis_core_role_permissions"."role_id" = \'fund-executive-most\'', 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id" FROM "emeis_core_acl" WHERE "emeis_core_acl"."user_id" = \'fb0e22c7-9ac7-5679-e988-1e6ba183b354\'::uuid', @@ -1060,7 +1338,7 @@ "queries": [ 'SELECT "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_role" ORDER BY "emeis_core_role"."slug" ASC', 'SELECT ("emeis_core_role_permissions"."role_id") AS "_prefetch_related_val_role_id", "emeis_core_permission"."created_at", "emeis_core_permission"."modified_at", "emeis_core_permission"."created_by_user_id", "emeis_core_permission"."metainfo", "emeis_core_permission"."slug", "emeis_core_permission"."name", "emeis_core_permission"."description" FROM "emeis_core_permission" INNER JOIN "emeis_core_role_permissions" ON ("emeis_core_permission"."slug" = "emeis_core_role_permissions"."permission_id") WHERE "emeis_core_role_permissions"."role_id" IN (\'front-her-occur\', \'kid-owner-car\', \'note-act-source\', \'run-too-successful\')', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") WHERE "emeis_core_acl"."role_id" IN (\'front-her-occur\', \'kid-owner-car\', \'note-act-source\', \'run-too-successful\')', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") WHERE "emeis_core_acl"."role_id" IN (\'front-her-occur\', \'kid-owner-car\', \'note-act-source\', \'run-too-successful\')', 'SELECT "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_role" INNER JOIN "emeis_core_role_permissions" ON ("emeis_core_role"."slug" = "emeis_core_role_permissions"."role_id") WHERE "emeis_core_role_permissions"."permission_id" = \'program-small\' ORDER BY "emeis_core_role"."slug" ASC', ], "request": { @@ -1192,8 +1470,44 @@ snapshots["test_api_list[ScopeViewSet] 1"] = { "queries": [ - 'SELECT "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level" FROM "emeis_core_scope" ORDER BY ("emeis_core_scope"."full_name" -> \'en\') ASC', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid, \'ea416ed0-759d-46a8-de58-f63a59077499\'::uuid, \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid)', + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY ("emeis_core_scope"."name" -> \'en\') ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE (__tree.tree_pk = emeis_core_scope.id) ORDER BY ("__tree".tree_ordering) ASC""", + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid, \'ea416ed0-759d-46a8-de58-f63a59077499\'::uuid, \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid)', ], "request": { "CONTENT_TYPE": "application/octet-stream", @@ -1294,7 +1608,7 @@ snapshots["test_api_list[UserViewSet] 1"] = { "queries": [ 'SELECT "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined" FROM "emeis_core_user"', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."user_id" IN (\'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid, \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid, \'ea416ed0-759d-46a8-de58-f63a59077499\'::uuid, \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid)', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."user_id" IN (\'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid, \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid, \'ea416ed0-759d-46a8-de58-f63a59077499\'::uuid, \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid)', ], "request": { "CONTENT_TYPE": "application/octet-stream", @@ -1408,9 +1722,82 @@ snapshots["test_api_patch[ACLViewSet] 1"] = { "queries": [ - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid LIMIT 21', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid LIMIT 21', + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" IN (\'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid) AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC""", + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" = \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC LIMIT 21""", 'SELECT "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined" FROM "emeis_core_user" WHERE "emeis_core_user"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', - 'SELECT "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level" FROM "emeis_core_scope" WHERE "emeis_core_scope"."id" = \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid LIMIT 21', 'SELECT "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_role" WHERE "emeis_core_role"."slug" = \'fund-executive-most\' LIMIT 21', 'SELECT (1) AS "a" FROM "emeis_core_acl" WHERE ("emeis_core_acl"."role_id" = \'fund-executive-most\' AND "emeis_core_acl"."scope_id" = \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid AND "emeis_core_acl"."user_id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid AND NOT ("emeis_core_acl"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid)) LIMIT 1', 'UPDATE "emeis_core_acl" SET "created_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "modified_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "created_by_user_id" = NULL, "metainfo" = \'{}\', "user_id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid, "scope_id" = \'9336ebf2-5087-d91c-818e-e6e9ec29f8c1\'::uuid, "role_id" = \'fund-executive-most\' WHERE "emeis_core_acl"."id" = \'f561aaf6-ef0b-f14d-4208-bb46a4ccb3ad\'::uuid', @@ -1500,7 +1887,7 @@ snapshots["test_api_patch[RoleViewSet] 1"] = { "queries": [ 'SELECT "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_role" WHERE "emeis_core_role"."slug" = \'note-act-source\' LIMIT 21', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") WHERE "emeis_core_acl"."role_id" IN (\'note-act-source\')', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") WHERE "emeis_core_acl"."role_id" IN (\'note-act-source\')', 'SELECT (1) AS "a" FROM "emeis_core_role" WHERE ("emeis_core_role"."slug" = \'note-act-source\' AND NOT ("emeis_core_role"."slug" = \'note-act-source\')) LIMIT 1', """UPDATE "emeis_core_role" SET "created_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "modified_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "created_by_user_id" = NULL, "metainfo" = \'{}\', "name" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Erin Scott\',\'\',\'\']), "description" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Far bit among again. Station story first. Team suggest traditional boy above. Central meeting anyone remember. There today material minute ago get. Range whose scientist draw free property consider.\',\'\',\'\']) WHERE "emeis_core_role"."slug" = \'note-act-source\'""", @@ -1543,11 +1930,83 @@ snapshots["test_api_patch[ScopeViewSet] 1"] = { "queries": [ - 'SELECT "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level" FROM "emeis_core_scope" WHERE "emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', - 'SELECT "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level" FROM "emeis_core_scope" WHERE "emeis_core_scope"."parent_id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid ORDER BY "emeis_core_scope"."tree_id" ASC, "emeis_core_scope"."lft" ASC', - """UPDATE "emeis_core_scope" SET "created_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "modified_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "created_by_user_id" = NULL, "metainfo" = \'{}\', "name" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Pamela Horton\',\'\',\'\']), "full_name" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Pamela Horton\',\'Pamela Horton\',\'Pamela Horton\']), "description" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Effort meet relationship far. Option program interesting station. First where during teach country talk across. -Argue move appear catch toward help wind. Material minute ago get.\',\'\',\'\']), "parent_id" = NULL, "is_active" = true WHERE "emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid""", + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY ("emeis_core_scope"."name" -> \'en\') ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC LIMIT 21""", + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."scope_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', + """ + WITH RECURSIVE __rank_table( + + "id", + "parent_id", + "rank_order" + ) AS ( + SELECT "emeis_core_scope"."id", "emeis_core_scope"."parent_id", ROW_NUMBER() OVER (ORDER BY "emeis_core_scope"."name" ASC) AS "rank_order" FROM "emeis_core_scope" + ), + __tree ( + + "tree_depth", + "tree_path", + "tree_ordering", + "tree_pk" + ) AS ( + SELECT + + 0, + array[T.id], + array[T.rank_order], + T."id" + FROM __rank_table T + WHERE T."parent_id" IS NULL + + UNION ALL + + SELECT + + __tree.tree_depth + 1, + __tree.tree_path || T.id, + __tree.tree_ordering || T.rank_order, + T."id" + FROM __rank_table T + JOIN __tree ON T."parent_id" = __tree.tree_pk + ) + SELECT (__tree.tree_depth) AS "tree_depth", (__tree.tree_path) AS "tree_path", (__tree.tree_ordering) AS "tree_ordering", "emeis_core_scope"."parent_id", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."is_active" FROM "emeis_core_scope" , "__tree" WHERE ("emeis_core_scope"."parent_id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid AND (__tree.tree_pk = emeis_core_scope.id)) ORDER BY ("__tree".tree_ordering) ASC""", + """UPDATE "emeis_core_scope" SET "parent_id" = NULL, "created_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "modified_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "created_by_user_id" = NULL, "metainfo" = \'{}\', "name" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Pamela Horton\',\'\',\'\']), "full_name" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Pamela Horton\',\'Pamela Horton\',\'Pamela Horton\']), "description" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'Effort meet relationship far. Option program interesting station. First where during teach country talk across. +Argue move appear catch toward help wind. Material minute ago get.\',\'\',\'\']), "is_active" = true WHERE "emeis_core_scope"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid""", ], "request": { "CONTENT_LENGTH": "614", @@ -1592,7 +2051,7 @@ snapshots["test_api_patch[UserViewSet] 1"] = { "queries": [ 'SELECT "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined" FROM "emeis_core_user" WHERE "emeis_core_user"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid LIMIT 21', - 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_scope"."created_at", "emeis_core_scope"."modified_at", "emeis_core_scope"."created_by_user_id", "emeis_core_scope"."metainfo", "emeis_core_scope"."id", "emeis_core_scope"."name", "emeis_core_scope"."full_name", "emeis_core_scope"."description", "emeis_core_scope"."parent_id", "emeis_core_scope"."is_active", "emeis_core_scope"."lft", "emeis_core_scope"."rght", "emeis_core_scope"."tree_id", "emeis_core_scope"."level", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_scope" ON ("emeis_core_acl"."scope_id" = "emeis_core_scope"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', + 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id", "emeis_core_user"."password", "emeis_core_user"."last_login", "emeis_core_user"."created_at", "emeis_core_user"."modified_at", "emeis_core_user"."created_by_user_id", "emeis_core_user"."metainfo", "emeis_core_user"."id", "emeis_core_user"."username", "emeis_core_user"."first_name", "emeis_core_user"."last_name", "emeis_core_user"."email", "emeis_core_user"."phone", "emeis_core_user"."language", "emeis_core_user"."address", "emeis_core_user"."city", "emeis_core_user"."zip", "emeis_core_user"."is_active", "emeis_core_user"."date_joined", "emeis_core_role"."created_at", "emeis_core_role"."modified_at", "emeis_core_role"."created_by_user_id", "emeis_core_role"."metainfo", "emeis_core_role"."slug", "emeis_core_role"."name", "emeis_core_role"."description" FROM "emeis_core_acl" INNER JOIN "emeis_core_user" ON ("emeis_core_acl"."user_id" = "emeis_core_user"."id") INNER JOIN "emeis_core_role" ON ("emeis_core_acl"."role_id" = "emeis_core_role"."slug") WHERE "emeis_core_acl"."user_id" IN (\'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)', 'SELECT (1) AS "a" FROM "emeis_core_user" WHERE ("emeis_core_user"."username" = \'mark48\' AND NOT ("emeis_core_user"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid)) LIMIT 1', 'UPDATE "emeis_core_user" SET "password" = \'_nNx5pap05\', "last_login" = \'2021-07-20T12:00:00+00:00\'::timestamptz, "created_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "modified_at" = \'2017-05-21T00:00:00+00:00\'::timestamptz, "created_by_user_id" = NULL, "metainfo" = \'{}\', "username" = \'mark48\', "first_name" = \'Amanda\', "last_name" = \'Gallagher\', "email" = \'kennethgarcia@example.org\', "phone" = NULL, "language" = \'en\', "address" = NULL, "city" = hstore(ARRAY[\'en\',\'de\',\'fr\'], ARRAY[\'\',\'\',\'\']), "zip" = NULL, "is_active" = true, "date_joined" = \'2017-05-21T00:00:00+00:00\'::timestamptz WHERE "emeis_core_user"."id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid', 'SELECT "emeis_core_acl"."created_at", "emeis_core_acl"."modified_at", "emeis_core_acl"."created_by_user_id", "emeis_core_acl"."metainfo", "emeis_core_acl"."id", "emeis_core_acl"."user_id", "emeis_core_acl"."scope_id", "emeis_core_acl"."role_id" FROM "emeis_core_acl" WHERE "emeis_core_acl"."user_id" = \'9dd4e461-268c-8034-f5c8-564e155c67a6\'::uuid', diff --git a/emeis/core/tests/test_api.py b/emeis/core/tests/test_api.py index 50caf838..496b783a 100644 --- a/emeis/core/tests/test_api.py +++ b/emeis/core/tests/test_api.py @@ -1,4 +1,5 @@ """Module to test api in a generic way.""" + import hashlib import json import re @@ -11,6 +12,8 @@ from django.urls import reverse from rest_framework_json_api.renderers import JSONRenderer +from emeis.core.models import Scope + from ..views import ( ACLViewSet, PermissionViewSet, @@ -188,6 +191,10 @@ def test_api_create(transactional_db, fixture, admin_client, viewset, snapshot): @pytest.mark.freeze_time("2017-05-21") def test_api_patch(fixture, admin_client, viewset, snapshot): + if isinstance(fixture, Scope): + # We need to get Scope through it's Tree manager, to get access to it's + # CTE attributes + fixture = Scope.objects.get(pk=fixture.pk) url = reverse("{0}-detail".format(viewset.base_name), args=[fixture.pk]) serializer = viewset.serializer_class(fixture) @@ -214,8 +221,8 @@ def test_api_destroy(fixture, admin_client, snapshot, viewset): @pytest.mark.parametrize( "set_new_parent_to, expect_error", [ - ("self", "A node may not be made a child of itself."), - ("child", "A node may not be made a child of any of its descendants."), + ("self", "A node cannot be made a descendant of itself."), + ("child", "A node cannot be made a descendant of itself."), ], ) def test_validate_circular_parents( diff --git a/emeis/core/tests/test_create_scope_command.py b/emeis/core/tests/test_create_scope_command.py index 25736132..84824ba8 100644 --- a/emeis/core/tests/test_create_scope_command.py +++ b/emeis/core/tests/test_create_scope_command.py @@ -142,12 +142,21 @@ def test_param_validation( ], ) def test_create_success( - transactional_db, capsys, cmd_args, expect_out, expect_err, role, user, scope, acl + transactional_db, + capsys, + cmd_args, + expect_out, + expect_err, + role, + user, + scope, + acl, ): _replace_in_args(cmd_args, user=user, role=role, scope=scope) + count_before = Scope.objects.count() call_command("create_scope", *cmd_args) - new_scope = Scope.objects.all().order_by("created_at").last() + new_scope = Scope.objects.all().order_siblings_by("created_at").last() new_acl = ACL.objects.all().order_by("created_at").last() def replace_expectations(in_str): @@ -165,7 +174,8 @@ def replace_expectations(in_str): if not expect_err: # Check that a scope has indeed been created - assert new_scope != scope + count_after = Scope.objects.count() + assert count_before + 1 == count_after stdout, stderr = capsys.readouterr() if isinstance(expect_out, dict): diff --git a/emeis/core/tests/test_models.py b/emeis/core/tests/test_models.py index 8a701476..8e9fb828 100644 --- a/emeis/core/tests/test_models.py +++ b/emeis/core/tests/test_models.py @@ -3,10 +3,10 @@ import pytest from django.contrib.auth.backends import ModelBackend from django.contrib.auth.base_user import BaseUserManager +from django.core.exceptions import ValidationError from django.utils import translation from hypothesis import given from hypothesis.strategies import emails, text -from mptt.exceptions import InvalidMove from ..models import Scope, User @@ -39,8 +39,9 @@ def test_scope_model(db): assert scope.parent.name["en"] == "parent scope" parent_scope.parent = scope - with pytest.raises(InvalidMove): + with pytest.raises(ValidationError) as excinfo: parent_scope.save() + assert excinfo.match("A node cannot be made a descendant of itself.") def test_scope_deletion(db, scope_factory): @@ -56,7 +57,8 @@ def test_scope_deletion(db, scope_factory): child.delete() assert Scope.objects.count() == 3 - assert list(Scope.objects.root_nodes()) == [root] + + assert list(Scope.objects.filter(parent=None)) == [root] def test_can_authenticate(db, user): diff --git a/emeis/core/tests/test_prefetch_visibility.py b/emeis/core/tests/test_prefetch_visibility.py index 80140dcf..b156d3b6 100644 --- a/emeis/core/tests/test_prefetch_visibility.py +++ b/emeis/core/tests/test_prefetch_visibility.py @@ -40,7 +40,7 @@ def test_invisible_acl_in_users( with CaptureQueriesContext(connection) as context: resp = admin_client.get(url, {"include": include}) - assert len(context.captured_queries) == 2 + assert len(context.captured_queries) == 3 collected_acl_rels = [ acl["id"] diff --git a/emeis/core/tests/test_views.py b/emeis/core/tests/test_views.py index 5c3b86be..c1486f9a 100644 --- a/emeis/core/tests/test_views.py +++ b/emeis/core/tests/test_views.py @@ -3,6 +3,7 @@ import pyexcel import pytest from django.urls import reverse +from django.utils import translation from rest_framework.status import ( HTTP_200_OK, HTTP_201_CREATED, @@ -290,11 +291,12 @@ def test_order_scopes_by_full_name(client, scope_factory, settings): } for lang in ["de", "en"]: - resp = client.get( - reverse("scope-list"), - {"sort": "full_name"}, - HTTP_ACCEPT_LANGUAGE=lang, - ) + with translation.override(lang): + resp = client.get( + reverse("scope-list"), + {"sort": "full_name"}, + HTTP_ACCEPT_LANGUAGE=lang, + ) received_names = [ entry["attributes"]["full-name"][lang] for entry in resp.json()["data"] ] diff --git a/emeis/core/utils.py b/emeis/core/utils.py index 970a9ba3..36542484 100644 --- a/emeis/core/utils.py +++ b/emeis/core/utils.py @@ -1,22 +1,7 @@ -import mptt -import mptt.managers from django.conf import settings from django.utils import translation -def rebuild_mptt_model(model): - """ - Rebuild an mptt model. - - This is used in migrations that work with data from mptt models. - """ - manager = mptt.managers.TreeManager() - manager.model = model - mptt.register(model) - manager.contribute_to_class(model, "objects") - manager.rebuild() - - def forced_or_current_lang(model_name): """Return the currently to-be-used language for the given model. diff --git a/emeis/core/views.py b/emeis/core/views.py index 5f7c8d5e..fa5046f4 100644 --- a/emeis/core/views.py +++ b/emeis/core/views.py @@ -189,7 +189,12 @@ def _order_field_suffix_if_needed(field_name): new_ordering = [_order_field_suffix_if_needed(field) for field in ordering] - qs = qs.order_by(*new_ordering) + if qs.model is models.Scope: + # django-tree-queries only supports ordering within siblings, not across + # everything. And uses another method for it + qs = qs.order_siblings_by(*new_ordering) + else: + qs = qs.order_by(*new_ordering) return qs @@ -263,7 +268,11 @@ class PermissionViewSet(BaseViewset): class ACLViewSet(BaseViewset): serializer_class = serializers.ACLSerializer - queryset = models.ACL.objects.all().select_related("user", "scope", "role") + queryset = ( + models.ACL.objects.all() + .select_related("user", "role") + .prefetch_related(Prefetch("scope", queryset=models.Scope.objects.all())) + ) filterset_class = filters.ACLFilterset search_fields = [ "scope__name", diff --git a/emeis/settings.py b/emeis/settings.py index 7afab420..65043c40 100644 --- a/emeis/settings.py +++ b/emeis/settings.py @@ -36,7 +36,6 @@ def default(default_dev=env.NOTSET, default_prod=env.NOTSET): "django.contrib.contenttypes", "django.contrib.auth", "mozilla_django_oidc", - "mptt", "generic_permissions.apps.GenericPermissionsConfig", "emeis.core.apps.DefaultConfig", ] diff --git a/requirements-base.txt b/requirements-base.txt index 2959c94b..b68a5902 100644 --- a/requirements-base.txt +++ b/requirements-base.txt @@ -4,8 +4,8 @@ django-environ>=0.10,<=0.11.2 django-filter>=22.1,<=23.5 django-generic-api-permissions==0.2.0 django-localized-fields==6.7 -django_mptt==0.15.0 django-postgres-extra==2.0.8 +django-tree-queries==0.19.0 djangorestframework==3.14.0 djangorestframework-jsonapi==6.1.0 mozilla-django-oidc==3.0.0 @@ -14,4 +14,3 @@ pyexcel-xlsx==0.6.0 requests==2.31.0 uwsgi==2.0.23 openpyxl==3.0.10 # TODO: dependency of `pyexcel-xlsx` Remove as soon as https://github.com/pyexcel/pyexcel-xlsx/issues/52 is resolved. - diff --git a/setup.py b/setup.py index b21a24b4..4a2d612c 100644 --- a/setup.py +++ b/setup.py @@ -40,7 +40,7 @@ "django-filter<24", "django-generic-api-permissions<1", "django-localized-fields>=6.4,<7", - "django_mptt>=0.11,<2", + "django-tree-queries>=0.19.0", "django-postgres-extra<3", "djangorestframework>=3.12.4,<4", "djangorestframework-jsonapi>=4.3.0,<=6.1.0",