Skip to content

Commit

Permalink
ClientSideGetMultipleNamespaces: push some predicates down to the ser…
Browse files Browse the repository at this point in the history
…ver (#7758)
  • Loading branch information
adutra authored Nov 28, 2023
1 parent 720a3d2 commit b539552
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import org.projectnessie.client.builder.BaseGetMultipleNamespacesBuilder;
import org.projectnessie.error.NessieNotFoundException;
import org.projectnessie.error.NessieReferenceNotFoundException;
import org.projectnessie.model.Content;
import org.projectnessie.model.ContentKey;
import org.projectnessie.model.EntriesResponse;
import org.projectnessie.model.GetMultipleContentsResponse;
Expand All @@ -38,7 +37,7 @@
/**
* Supports previous "get multiple namespaces" functionality of the java client over Nessie API v2.
*
* <p>API v2 does not have methods dedicated to manging namespaces. Namespaces are expected to be
* <p>API v2 does not have methods dedicated to managing namespaces. Namespaces are expected to be
* managed as ordinary content objects.
*/
public final class ClientSideGetMultipleNamespaces extends BaseGetMultipleNamespacesBuilder {
Expand All @@ -61,33 +60,24 @@ public GetNamespacesResponse get() throws NessieReferenceNotFoundException {
try {
GetEntriesBuilder getEntries = api.getEntries().refName(refName).hashOnRef(hashOnRef);

String filter = null;
String filter = "entry.contentType == 'NAMESPACE'";
if (namespace != null && !namespace.isEmpty()) {
String nsName = namespace.name();
filter =
filter +=
onlyDirectChildren
? format(
"size(entry.keyElements) == %d && entry.encodedKey.startsWith('%s.')",
" && size(entry.keyElements) == %d && entry.encodedKey.startsWith('%s.')",
namespace.getElementCount() + 1, nsName)
: format(
"entry.encodedKey == '%s' || entry.encodedKey.startsWith('%s.')",
"&& (entry.encodedKey == '%s' || entry.encodedKey.startsWith('%s.'))",
nsName, nsName);
} else if (onlyDirectChildren) {
filter = "size(entry.keyElements) == 1";
}
if (filter != null) {
getEntries.filter(filter);
filter += " && size(entry.keyElements) == 1";
}
getEntries.filter(filter);

entries =
getEntries.stream()
.filter(e -> Content.Type.NAMESPACE.equals(e.getType()))
.map(EntriesResponse.Entry::getName)
.filter(
name ->
namespace == null
|| Namespace.of(name.getElements()).isSameOrSubElementOf(namespace))
.collect(Collectors.toList());
getEntries.stream().map(EntriesResponse.Entry::getName).collect(Collectors.toList());
} catch (NessieNotFoundException e) {
throw new NessieReferenceNotFoundException(e.getMessage(), e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,16 @@ public void namespaces() throws Exception {
namespace4WithId = api().createNamespace().refName(mainName).namespace(namespace4).create();
}

// Add some non-namespace content to check that it is not returned by the namespace API
IcebergTable table = IcebergTable.of("irrelevant", 1, 2, 3, 4);
ContentKey table1 = ContentKey.of(namespace4, "table1");
api()
.commitMultipleOperations()
.branch(main)
.commitMeta(CommitMeta.fromMessage("Add table1"))
.operation(Put.of(table1, table))
.commit();

for (Map.Entry<Namespace, List<Namespace>> c :
ImmutableMap.of(
Namespace.EMPTY,
Expand Down Expand Up @@ -1569,15 +1579,39 @@ public void namespaces() throws Exception {
namespace1WithId, namespace2update2, namespace3WithId, namespace4WithId);

if (isV2()) {
// contains other namespaces
soft.assertThatThrownBy(
() -> api().deleteNamespace().refName(mainName).namespace(namespace2).delete())
.isInstanceOf(NessieNamespaceNotEmptyException.class)
.asInstanceOf(type(NessieNamespaceNotEmptyException.class))
.extracting(NessieNamespaceNotEmptyException::getErrorDetails)
.extracting(ContentKeyErrorDetails::contentKey)
.isEqualTo(namespace2.toContentKey());
// contains a table
soft.assertThatThrownBy(
() -> api().deleteNamespace().refName(mainName).namespace(namespace4).delete())
.isInstanceOf(NessieNamespaceNotEmptyException.class)
.asInstanceOf(type(NessieNamespaceNotEmptyException.class))
.extracting(NessieNamespaceNotEmptyException::getErrorDetails)
.extracting(ContentKeyErrorDetails::contentKey)
.isEqualTo(namespace4.toContentKey());
} else {
soft.assertThatThrownBy(
() -> api().deleteNamespace().refName(mainName).namespace(namespace2).delete())
.isInstanceOf(NessieNamespaceNotEmptyException.class);
soft.assertThatThrownBy(
() -> api().deleteNamespace().refName(mainName).namespace(namespace4).delete())
.isInstanceOf(NessieNamespaceNotEmptyException.class);
}

main = (Branch) api().getReference().refName(mainName).get();
api()
.commitMultipleOperations()
.branch(main)
.commitMeta(CommitMeta.fromMessage("Delete table1"))
.operation(Delete.of(table1))
.commit();

if (isV2()) {
main = (Branch) api().getReference().refName(mainName).get();
DeleteNamespaceResult response =
Expand Down

0 comments on commit b539552

Please sign in to comment.