예제 #1
0
    def execute(self, batch, **_):
        # Check that we can actually process this batch
        self._check_upsert_queries(batch,
                                   expected_keys=["authority", "username"])

        # Split users and their embedded identity lists
        users, identities = [], []

        for command in batch:
            attributes = deepcopy(command.body.attributes)

            identities.append(attributes.pop("identities"))
            users.append(attributes)

        # Upsert the data
        user_rows = self._upsert_user_table(users)
        self._upsert_identities(identities,
                                user_ids=[row[0] for row in user_rows])

        # Report back
        return [
            Report(id_,
                   public_id=User(authority=authority,
                                  _username=username).userid)
            for id_, authority, username in user_rows
        ]
예제 #2
0
    def execute(self, batch, effective_user_id=None, **_):  # pylint: disable=arguments-differ
        if effective_user_id is None:
            raise CommandSequenceError(
                "Effective user must be configured before upserting groups")

        # Check that we can actually process this batch
        self._check_upsert_queries(
            batch, expected_keys=["authority", "authority_provided_id"])

        static_values = {
            # Set the group to be owned by the effective user
            "creator_id": effective_user_id,
            # Set the group to match the specified type (private in this case)
            "joinable_by": self.type_flags.joinable_by,
            "readable_by": self.type_flags.readable_by,
            "writeable_by": self.type_flags.writeable_by,
        }

        # Prep the query
        values = [command.body.attributes for command in batch]
        for value in values:
            value.update(static_values)

        stmt = insert(Group).values(values)
        stmt = stmt.on_conflict_do_update(
            index_elements=["authority", "authority_provided_id"],
            set_={
                "name": stmt.excluded.name
            },
        ).returning(Group.id, Group.authority, Group.authority_provided_id)

        # Upsert the data
        try:
            group_rows = self._execute_statement(stmt).fetchall()

        except ProgrammingError as err:
            # https://www.postgresql.org/docs/9.4/errcodes-appendix.html
            # 21000 == cardinality violation
            if err.orig.pgcode == "21000":
                raise ConflictingDataError(
                    "Attempted to create two groups with the same authority and id"
                ) from err

            raise

        # Report back
        return [
            Report(
                id_,
                public_id=Group(
                    authority=authority,
                    authority_provided_id=authority_provided_id).groupid,
            ) for id_, authority, authority_provided_id in group_rows
        ]
예제 #3
0
    def execute(  # pylint: disable=arguments-differ
            self,
            batch,
            on_duplicate="continue",
            **_):
        """
        Execute GroupMembershipCreateAction.

        :param on_duplicate: Specify behavior when a record already exists. The
                             default is "continue"
        """
        if on_duplicate != "continue":
            raise UnsupportedOperationError(
                "Create modes other than 'continue' have not been implemented")

        values = [{
            "user_id": command.body.member.id,
            "group_id": command.body.group.id
        } for command in batch]

        stmt = insert(GroupMembership).values(values)

        # This update doesn't change the row, but it does count as it being
        # 'updated' which means we can get the values in the "RETURNING"
        # clause and do the select in one go
        stmt = stmt.on_conflict_do_update(
            index_elements=["user_id", "group_id"],
            set_={"user_id": stmt.excluded.user_id},
        )

        stmt = stmt.returning(GroupMembership.id)

        try:
            membership_rows = self._execute_statement(stmt).fetchall()

        except IntegrityError as err:
            # https://www.postgresql.org/docs/9.1/errcodes-appendix.html
            # 23503 = foreign_key_violation
            if err.orig.pgcode == "23503":
                raise ConflictingDataError(
                    "Cannot insert group membership as either the user or "
                    f"group specified does not exist: {err.params}") from err

            raise

        return [Report(id_) for (id_, ) in membership_rows]
예제 #4
0
    def execute(self, batch, effective_user_id=None, **_):
        if effective_user_id is None:
            raise CommandSequenceError(
                "Effective user must be configured before upserting groups")

        # Check that we can actually process this batch
        self._check_upsert_queries(
            batch, expected_keys=["authority", "authority_provided_id"])

        static_values = {
            # Set the group to be owned by the effective user
            "creator_id": effective_user_id,
            # Set the group to match the specified type (private in this case)
            "joinable_by": self.type_flags.joinable_by,
            "readable_by": self.type_flags.readable_by,
            "writeable_by": self.type_flags.writeable_by,
        }

        # Prep the query
        values = [command.body.attributes for command in batch]
        for value in values:
            value.update(static_values)

        stmt = insert(Group).values(values)
        stmt = stmt.on_conflict_do_update(
            index_elements=["authority", "authority_provided_id"],
            set_={
                "name": stmt.excluded.name
            },
        ).returning(Group.id, Group.authority, Group.authority_provided_id)

        # Upsert the data
        group_rows = self._execute_statement(stmt).fetchall()

        # Report back
        return [
            Report(
                id_,
                public_id=Group(
                    authority=authority,
                    authority_provided_id=authority_provided_id).groupid,
            ) for id_, authority, authority_provided_id in group_rows
        ]