Skip to content

Commit

Permalink
fix n+1 select in /api/vaults/{vaultId}/members
Browse files Browse the repository at this point in the history
  • Loading branch information
overheadhunter committed Sep 6, 2023
1 parent 92b4fb3 commit d0d4288
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 8 deletions.
14 changes: 6 additions & 8 deletions backend/src/main/java/org/cryptomator/hub/api/VaultResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,15 @@ public List<VaultDto> getAllVaults() {
@VaultRole(VaultAccess.Role.OWNER) // may throw 403
@Transactional
@Produces(MediaType.APPLICATION_JSON)
@Operation(summary = "list vault members", description = "list all users that this vault has been shared with")
@Operation(summary = "list vault members", description = "list all users or groups that this vault has been shared with directly (not inherited via group membership)")
@APIResponse(responseCode = "200")
@APIResponse(responseCode = "403", description = "not a vault owner")
public List<MemberDto> getMembers(@PathParam("vaultId") UUID vaultId) {
var vault = Vault.<Vault>findById(vaultId); // should always be found, since @VaultRole filter would have triggered

return vault.directMembers.stream().map(authority -> {
VaultAccess access = VaultAccess.findById(new VaultAccess.Id(vaultId, authority.id)); // TODO: inefficient, would be better if role is already part of the query result
if (authority instanceof User u) {
public List<MemberDto> getDirectMembers(@PathParam("vaultId") UUID vaultId) {
return VaultAccess.forVault(vaultId).map(access -> {
// TODO switch to switch expressions, once we can make Authority sealed
if (access.authority instanceof User u) {
return MemberDto.fromEntity(u, access.role);
} else if (authority instanceof Group g) {
} else if (access.authority instanceof Group g) {
return MemberDto.fromEntity(g, access.role);
} else {
throw new IllegalStateException();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.cryptomator.hub.entities;

import io.quarkus.hibernate.orm.panache.PanacheEntityBase;
import io.quarkus.panache.common.Parameters;
import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
Expand All @@ -10,14 +11,24 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.MapsId;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Table;

import java.io.Serializable;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Stream;

@Entity
@Table(name = "vault_access")
@NamedQuery(name = "VaultAccess.forVault",
query = """
SELECT va
FROM VaultAccess va
INNER JOIN FETCH va.vault
INNER JOIN FETCH va.authority
WHERE va.id.vaultId = :vaultId
""")
public class VaultAccess extends PanacheEntityBase {

@EmbeddedId
Expand Down Expand Up @@ -49,6 +60,10 @@ public enum Role {
OWNER
}

public static Stream<VaultAccess> forVault(UUID vaultId) {
return find("#VaultAccess.forVault", Parameters.with("vaultId", vaultId)).stream();
}

@Embeddable
public static class Id implements Serializable {

Expand Down

0 comments on commit d0d4288

Please sign in to comment.