refactor!: implement lazy iterators for several APIs (#4459)

Implement lazy iterators for:
- secrets
- views
- jobs
- functions
- materialized views
This commit is contained in:
Colin Patrick McCabe
2026-10-07 10:24:20 -07:00
committed by GitHub
parent 069b2f7d31
commit de005f1d61
32 changed files with 2185 additions and 454 deletions
+28 -14
View File
@@ -371,13 +371,15 @@ impl Connection {
}
#[napi(catch_unwind)]
pub async fn list_materialized_views(&self) -> napi::Result<Vec<String>> {
let views = self
.get_inner()?
.list_materialized_views()
.await
.default_error()?;
Ok(views)
pub fn list_materialized_views(
&self,
page_token: Option<String>,
page_limit: Option<u32>,
) -> napi::Result<crate::listing::NameListing> {
Ok(crate::listing::NameListing::new(
self.get_inner()?
.list_materialized_views(crate::listing::options(page_token, page_limit)),
))
}
/// Drop a materialized view.
@@ -460,12 +462,18 @@ impl Connection {
/// The names of the views in one namespace.
#[napi(catch_unwind)]
pub async fn list_views(
pub fn list_views(
&self,
namespace_path: Option<Vec<String>>,
) -> napi::Result<Vec<String>> {
let ns = namespace_path.unwrap_or_default();
self.get_inner()?.list_views(&ns).await.default_error()
page_token: Option<String>,
page_limit: Option<u32>,
) -> napi::Result<crate::listing::NameListing> {
Ok(crate::listing::NameListing::new(
self.get_inner()?.list_views(
&namespace_path.unwrap_or_default(),
crate::listing::options(page_token, page_limit),
),
))
}
/// Start dropping a materialized view and return its cleanup job.
@@ -588,9 +596,15 @@ impl Connection {
/// List server-side jobs across the database's tables.
#[napi(catch_unwind)]
pub async fn list_jobs(&self) -> napi::Result<Vec<crate::job::JobInfo>> {
let jobs = self.get_inner()?.list_jobs().await.default_error()?;
Ok(jobs.into_iter().map(Into::into).collect())
pub fn list_jobs(
&self,
page_token: Option<String>,
page_limit: Option<u32>,
) -> napi::Result<crate::listing::JobListing> {
Ok(crate::listing::JobListing::new(
self.get_inner()?
.list_jobs(crate::listing::options(page_token, page_limit)),
))
}
/// Request cancellation of a server-side job by id. Returns true if the
+1
View File
@@ -18,6 +18,7 @@ mod header;
mod index;
mod iterator;
mod job;
mod listing;
pub mod merge;
pub mod otel;
pub mod permutation;
+83
View File
@@ -0,0 +1,83 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright The LanceDB Authors
use crate::error::NapiErrorExt;
use futures::{StreamExt, future::poll_fn};
use lancedb::listing::{Listing, ListingOptions};
use napi_derive::napi;
use std::sync::Mutex;
pub fn options(page_token: Option<String>, page_limit: Option<u32>) -> ListingOptions {
let mut options = ListingOptions::default();
options.page_token = page_token;
options.page_limit = page_limit;
options
}
#[napi]
pub struct NameListing {
inner: Mutex<Listing<String>>,
next_lock: futures::lock::Mutex<()>,
}
impl NameListing {
pub fn new(inner: Listing<String>) -> Self {
Self {
inner: Mutex::new(inner),
next_lock: futures::lock::Mutex::new(()),
}
}
}
#[napi]
impl NameListing {
#[napi]
pub fn num_page_results(&self) -> u32 {
self.inner.lock().unwrap().num_page_results() as u32
}
#[napi]
pub fn page_token(&self) -> Option<String> {
self.inner.lock().unwrap().page_token().map(str::to_owned)
}
#[napi]
pub async fn next(&self) -> napi::Result<Option<String>> {
let _guard = self.next_lock.lock().await;
let value = poll_fn(|cx| self.inner.lock().unwrap().poll_next_unpin(cx))
.await
.transpose()
.default_error()?;
Ok(value)
}
}
#[napi]
pub struct JobListing {
inner: Mutex<Listing<lancedb::database::JobInfo>>,
next_lock: futures::lock::Mutex<()>,
}
impl JobListing {
pub fn new(inner: Listing<lancedb::database::JobInfo>) -> Self {
Self {
inner: Mutex::new(inner),
next_lock: futures::lock::Mutex::new(()),
}
}
}
#[napi]
impl JobListing {
#[napi]
pub fn num_page_results(&self) -> u32 {
self.inner.lock().unwrap().num_page_results() as u32
}
#[napi]
pub fn page_token(&self) -> Option<String> {
self.inner.lock().unwrap().page_token().map(str::to_owned)
}
#[napi]
pub async fn next(&self) -> napi::Result<Option<crate::job::JobInfo>> {
let _guard = self.next_lock.lock().await;
let value = poll_fn(|cx| self.inner.lock().unwrap().poll_next_unpin(cx))
.await
.transpose()
.default_error()?;
Ok(value.map(|value| value.into()))
}
}