This is an automated email from the ASF dual-hosted git repository.

fresh-borzoni pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fluss-rust.git


The following commit(s) were added to refs/heads/main by this push:
     new 4e64847c [elixir] feat: Add get_database_info admin call (#586)
4e64847c is described below

commit 4e64847c0bd9824cc77dce65a252ab595e5faa3e
Author: Nicoleta Lazar <[email protected]>
AuthorDate: Wed Jun 3 13:38:36 2026 +0100

    [elixir] feat: Add get_database_info admin call (#586)
    
    This commit adds the `get_database_info` admin call on `Fluss.Admin`,
    returning a `Fluss.DatabaseInfo` struct that embeds a nested
    `Fluss.DatabaseDescriptor` (comment + custom properties).
    
    The output-marshaling pattern follows the wrapper convention
    established by `get_server_nodes` in #583: bindings-local `Nif*`
    structs with `from_core` builders, derived `NifStruct` for cross-FFI
    encoding.
    
    Part of #466.
---
 bindings/elixir/lib/fluss/admin.ex               | 16 ++++++++
 bindings/elixir/lib/fluss/database_descriptor.ex | 34 ++++++++++++++++
 bindings/elixir/lib/fluss/database_info.ex       | 37 +++++++++++++++++
 bindings/elixir/lib/fluss/native.ex              |  2 +
 bindings/elixir/native/fluss_nif/src/admin.rs    | 51 +++++++++++++++++++++++-
 bindings/elixir/test/integration/admin_test.exs  | 19 +++++++++
 6 files changed, 158 insertions(+), 1 deletion(-)

diff --git a/bindings/elixir/lib/fluss/admin.ex 
b/bindings/elixir/lib/fluss/admin.ex
index 3be8e96f..8a8ae9c4 100644
--- a/bindings/elixir/lib/fluss/admin.ex
+++ b/bindings/elixir/lib/fluss/admin.ex
@@ -72,6 +72,22 @@ defmodule Fluss.Admin do
     |> Native.await_nif()
   end
 
+  @spec get_database_info(t(), String.t()) ::
+          {:ok, Fluss.DatabaseInfo.t()} | {:error, Fluss.Error.t()}
+  def get_database_info(admin, database_name) do
+    admin
+    |> Native.admin_get_database_info(database_name)
+    |> Native.await_nif()
+  end
+
+  @spec get_database_info!(t(), String.t()) :: Fluss.DatabaseInfo.t()
+  def get_database_info!(admin, database_name) do
+    case get_database_info(admin, database_name) do
+      {:ok, info} -> info
+      {:error, %Fluss.Error{} = err} -> raise err
+    end
+  end
+
   @spec drop_database(t(), String.t(), boolean()) :: :ok | {:error, 
Fluss.Error.t()}
   def drop_database(admin, name, ignore_if_not_exists \\ true) do
     admin
diff --git a/bindings/elixir/lib/fluss/database_descriptor.ex 
b/bindings/elixir/lib/fluss/database_descriptor.ex
new file mode 100644
index 00000000..71fdc963
--- /dev/null
+++ b/bindings/elixir/lib/fluss/database_descriptor.ex
@@ -0,0 +1,34 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+defmodule Fluss.DatabaseDescriptor do
+  @moduledoc """
+  User-supplied configuration of a Fluss database — its comment and any custom
+  properties.
+
+  Embedded as the `:descriptor` field of `Fluss.DatabaseInfo`; produced
+  indirectly via `Fluss.Admin.get_database_info/2`.
+  """
+
+  @enforce_keys [:comment, :custom_properties]
+  defstruct [:comment, :custom_properties]
+
+  @type t :: %__MODULE__{
+          comment: String.t() | nil,
+          custom_properties: %{optional(String.t()) => String.t()}
+        }
+end
diff --git a/bindings/elixir/lib/fluss/database_info.ex 
b/bindings/elixir/lib/fluss/database_info.ex
new file mode 100644
index 00000000..59afb1d4
--- /dev/null
+++ b/bindings/elixir/lib/fluss/database_info.ex
@@ -0,0 +1,37 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+defmodule Fluss.DatabaseInfo do
+  @moduledoc """
+  Metadata about a Fluss database: name, descriptor, and creation/modification
+  timestamps as tracked by the cluster.
+
+  Returned by `Fluss.Admin.get_database_info/2`. The `:descriptor` field
+  holds a `Fluss.DatabaseDescriptor.t()` carrying the user-supplied comment and
+  custom properties.
+  """
+
+  @enforce_keys [:database_name, :descriptor, :created_time, :modified_time]
+  defstruct [:database_name, :descriptor, :created_time, :modified_time]
+
+  @type t :: %__MODULE__{
+          database_name: String.t(),
+          descriptor: Fluss.DatabaseDescriptor.t(),
+          created_time: integer(),
+          modified_time: integer()
+        }
+end
diff --git a/bindings/elixir/lib/fluss/native.ex 
b/bindings/elixir/lib/fluss/native.ex
index b0e41f04..20f193f8 100644
--- a/bindings/elixir/lib/fluss/native.ex
+++ b/bindings/elixir/lib/fluss/native.ex
@@ -30,6 +30,8 @@ defmodule Fluss.Native do
   def admin_create_database(_admin, _name, _ignore_if_exists),
     do: :erlang.nif_error(:nif_not_loaded)
 
+  def admin_get_database_info(_admin, _database_name), do: 
:erlang.nif_error(:nif_not_loaded)
+
   def admin_drop_database(_admin, _name, _ignore_if_not_exists),
     do: :erlang.nif_error(:nif_not_loaded)
 
diff --git a/bindings/elixir/native/fluss_nif/src/admin.rs 
b/bindings/elixir/native/fluss_nif/src/admin.rs
index ddb83e68..b765725a 100644
--- a/bindings/elixir/native/fluss_nif/src/admin.rs
+++ b/bindings/elixir/native/fluss_nif/src/admin.rs
@@ -20,9 +20,10 @@ use crate::atoms::to_nif_err;
 use crate::connection::ConnectionResource;
 use crate::schema::TableDescriptorResource;
 use fluss::client::FlussAdmin;
-use fluss::metadata::TablePath;
+use fluss::metadata::{DatabaseDescriptor, DatabaseInfo, TablePath};
 use fluss::{ServerNode, ServerType};
 use rustler::{Env, NifStruct, NifUnitEnum, ResourceArc, Term};
+use std::collections::HashMap;
 use std::sync::Arc;
 
 #[derive(NifUnitEnum)]
@@ -56,6 +57,42 @@ impl NifServerNode {
     }
 }
 
+#[derive(NifStruct)]
+#[module = "Fluss.DatabaseDescriptor"]
+pub struct NifDatabaseDescriptor {
+    pub comment: Option<String>,
+    pub custom_properties: HashMap<String, String>,
+}
+
+impl NifDatabaseDescriptor {
+    pub fn from_core(desc: &DatabaseDescriptor) -> Self {
+        Self {
+            comment: desc.comment().map(String::from),
+            custom_properties: desc.custom_properties().clone(),
+        }
+    }
+}
+
+#[derive(NifStruct)]
+#[module = "Fluss.DatabaseInfo"]
+pub struct NifDatabaseInfo {
+    pub database_name: String,
+    pub descriptor: NifDatabaseDescriptor,
+    pub created_time: i64,
+    pub modified_time: i64,
+}
+
+impl NifDatabaseInfo {
+    pub fn from_core(info: &DatabaseInfo) -> Self {
+        Self {
+            database_name: info.database_name().to_string(),
+            descriptor: 
NifDatabaseDescriptor::from_core(info.database_descriptor()),
+            created_time: info.created_time(),
+            modified_time: info.modified_time(),
+        }
+    }
+}
+
 pub struct AdminResource {
     pub inner: Arc<FlussAdmin>,
 }
@@ -97,6 +134,18 @@ fn admin_create_database<'a>(
     })
 }
 
+#[rustler::nif]
+fn admin_get_database_info<'a>(
+    env: Env<'a>,
+    admin: ResourceArc<AdminResource>,
+    database_name: String,
+) -> Term<'a> {
+    async_nif::spawn_task_with_result(env, async move {
+        let info: DatabaseInfo = 
admin.inner.get_database_info(&database_name).await?;
+        Ok(NifDatabaseInfo::from_core(&info))
+    })
+}
+
 #[rustler::nif]
 fn admin_drop_database<'a>(
     env: Env<'a>,
diff --git a/bindings/elixir/test/integration/admin_test.exs 
b/bindings/elixir/test/integration/admin_test.exs
index 1f670350..7942c5e3 100644
--- a/bindings/elixir/test/integration/admin_test.exs
+++ b/bindings/elixir/test/integration/admin_test.exs
@@ -53,6 +53,25 @@ defmodule Fluss.Integration.AdminTest do
     end
   end
 
+  describe "get_database_info/2" do
+    test "returns DatabaseInfo for an existing database", %{admin: admin} do
+      db = "fluss_data_sources_#{:rand.uniform(100_000)}"
+      :ok = Fluss.Admin.create_database(admin, db, true)
+      on_exit(fn -> Fluss.Admin.drop_database(admin, db, true) end)
+
+      assert {:ok, %Fluss.DatabaseInfo{} = info} = 
Fluss.Admin.get_database_info(admin, db)
+      assert info.database_name == db
+      assert %Fluss.DatabaseDescriptor{} = info.descriptor
+      assert is_integer(info.created_time)
+      assert is_integer(info.modified_time)
+    end
+
+    test "returns error for a non-existent database", %{admin: admin} do
+      db = "fluss_data_sources_#{:rand.uniform(100_000)}"
+      assert {:error, %Fluss.Error{}} = Fluss.Admin.get_database_info(admin, 
db)
+    end
+  end
+
   describe "database_exists/2" do
     test "returns {:ok, true} for an existing database", %{admin: admin} do
       db = "fluss_data_sources_#{:rand.uniform(100_000)}"

Reply via email to