nastra commented on code in PR #8857:
URL: https://github.com/apache/iceberg/pull/8857#discussion_r1404431932


##########
nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java:
##########
@@ -181,133 +186,206 @@ public IcebergTable table(TableIdentifier 
tableIdentifier) {
   }
 
   public void createNamespace(Namespace namespace, Map<String, String> 
metadata) {
+    getRef().checkMutable();
+    if (namespace.isEmpty()) {
+      throw new IllegalArgumentException("Creating empty namespaces is not 
supported");
+    }
+    ContentKey key = ContentKey.of(namespace.levels());
+    org.projectnessie.model.Namespace content =
+        org.projectnessie.model.Namespace.of(key.getElements(), metadata);
     try {
-      getRef().checkMutable();
-      withReference(
-              getApi()
-                  .createNamespace()
-                  
.namespace(org.projectnessie.model.Namespace.of(namespace.levels()))
-                  .properties(metadata))
-          .create();
-      refresh();
-    } catch (NessieNamespaceAlreadyExistsException e) {
-      throw new AlreadyExistsException(e, "Namespace already exists: %s", 
namespace);
+      Map<ContentKey, Content> contentMap =
+          api.getContent().reference(getReference()).key(key).get();
+      Content existing = contentMap.get(key);
+      if (existing != null) {
+        throw namespaceAlreadyExists(key, existing, null);
+      }
+      try {
+        commitRetry("create namespace " + key, Operation.Put.of(key, content));
+      } catch (NessieReferenceConflictException e) {
+        Optional<Conflict> conflict = NessieUtil.extractSingleConflict(e);
+        if (conflict.isPresent()) {
+          switch (conflict.get().conflictType()) {
+            case KEY_EXISTS:
+              Content conflicting = 
withReference(api.getContent()).key(key).get().get(key);
+              throw namespaceAlreadyExists(key, conflicting, e);
+            case NAMESPACE_ABSENT:
+              throw new NoSuchNamespaceException(
+                  e,
+                  "Cannot create Namespace '%s': parent namespace '%s' does 
not exist",
+                  namespace,
+                  conflict.get().key());
+          }
+        }
+        throw new RuntimeException(
+            String.format("Cannot create Namespace '%s': %s", namespace, 
e.getMessage()));
+      }
     } catch (NessieNotFoundException e) {
       throw new RuntimeException(
           String.format(
-              "Cannot create Namespace '%s': " + "ref '%s' is no longer 
valid.",
+              "Cannot create Namespace '%s': ref '%s' is no longer valid.",
               namespace, getRef().getName()),
           e);
+    } catch (BaseNessieClientServerException e) {
+      throw new RuntimeException(
+          String.format("Cannot create Namespace '%s': %s", namespace, 
e.getMessage()), e);
     }
   }
 
   public List<Namespace> listNamespaces(Namespace namespace) throws 
NoSuchNamespaceException {
     try {
-      GetNamespacesResponse response =
-          withReference(
-                  getApi()
-                      .getMultipleNamespaces()
-                      
.namespace(org.projectnessie.model.Namespace.of(namespace.levels())))
-              .get();
-      return response.getNamespaces().stream()
-          .map(ns -> Namespace.of(ns.getElements().toArray(new String[0])))
-          .filter(ns -> ns.length() == namespace.length() + 1)
+      org.projectnessie.model.Namespace root =
+          org.projectnessie.model.Namespace.of(namespace.levels());
+      String filter =
+          "entry.contentType == 'NAMESPACE' &&"
+              + (namespace.isEmpty()
+                  ? "size(entry.keyElements) == 1"
+                  : String.format(
+                      "size(entry.keyElements) == %d && 
entry.encodedKey.startsWith('%s.')",
+                      root.getElementCount() + 1, root.name()));
+      List<ContentKey> entries =
+          withReference(api.getEntries()).filter(filter).stream()
+              .map(EntriesResponse.Entry::getName)
+              .collect(Collectors.toList());
+      if (entries.isEmpty()) {
+        return Collections.emptyList();
+      }
+      GetContentBuilder getContent = withReference(api.getContent());
+      entries.forEach(getContent::key);
+      return getContent.get().values().stream()
+          .map(v -> v.unwrap(org.projectnessie.model.Namespace.class))
+          .filter(Optional::isPresent)
+          .map(Optional::get)
+          .map(v -> Namespace.of(v.getElements().toArray(new String[0])))
           .collect(Collectors.toList());
-    } catch (NessieReferenceNotFoundException e) {
+    } catch (NessieNotFoundException e) {
+      if (namespace.isEmpty()) {
+        throw new NoSuchNamespaceException(
+            e,
+            "Cannot list top-level Namespaces: ref '%s' is no longer valid.",
+            getRef().getName());
+      }
       throw new RuntimeException(
           String.format(
-              "Cannot list Namespaces starting from '%s': " + "ref '%s' is no 
longer valid.",
+              "Cannot list child Namespaces from '%s': ref '%s' is no longer 
valid.",
               namespace, getRef().getName()),
           e);
     }
   }
 
   public boolean dropNamespace(Namespace namespace) throws 
NamespaceNotEmptyException {
+    getRef().checkMutable();
+    ContentKey key = ContentKey.of(namespace.levels());
     try {
-      getRef().checkMutable();
-      withReference(
-              getApi()
-                  .deleteNamespace()
-                  
.namespace(org.projectnessie.model.Namespace.of(namespace.levels())))
-          .delete();
-      refresh();
-      return true;
-    } catch (NessieNamespaceNotFoundException e) {
-      return false;
+      Map<ContentKey, Content> contentMap =
+          api.getContent().reference(getReference()).key(key).get();
+      Content existing = contentMap.get(key);
+      if (existing != null && !unwrapNamespace(existing).isPresent()) {
+        throw new NoSuchNamespaceException(
+            "Content object with name '%s' is not a Namespace.", namespace);

Review Comment:
   you might want to check how other catalogs name this, but I _think_ 
lowercase is preferred



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@iceberg.apache.org
For additional commands, e-mail: issues-h...@iceberg.apache.org

Reply via email to