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 ]
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 ]
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]
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 ]