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)}"