reifydb-catalog 0.4.12

Database catalog and metadata management for ReifyDB
Documentation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2025 ReifyDB

//! User-facing API for defining virtual tables.
//!
//! This module provides simplified traits for users to implement custom virtual tables.
//! Users can choose between two levels of abstraction:
//!
//! - [`UserVTable`]: Simple API for tables that can return all rows at once
//! - [`UserVTableIterator`]: Advanced API for streaming large datasets with optional pushdown
//!
//! # Example
//!
//! ```ignore
//! use reifydb_catalog::vtable::user::{UserVTable, UserVTableColumn};
//! use reifydb_type::value::r#type::Type;
//! use reifydb_core::value::column::columns::Columns;
//!
//! struct MyApiTable {
//!     api_client: ApiClient,
//! }
//!
//! impl UserVTable for MyApiTable {
//!     fn definition(&self) -> Vec<UserVTableColumn> {
//!         vec![
//!             UserVTableColumn::new("id", Type::Uint8),
//!             UserVTableColumn::new("name", Type::Utf8),
//!         ]
//!     }
//!
//!     fn get(&self) -> Columns {
//!         // Return column-oriented data
//!         self.api_client.fetch_columns()
//!     }
//! }
//! ```

pub mod builder;
pub mod registry;

use reifydb_core::value::column::columns::Columns;
use reifydb_type::value::{Value, r#type::Type};

use crate::Result;

/// Column definition for user virtual tables.
#[derive(Debug, Clone)]
pub struct UserVTableColumn {
	/// Column name
	pub name: String,
	/// Column data type
	pub data_type: Type,
	/// Whether the column allows undefined values
	pub undefined: bool,
}

impl UserVTableColumn {
	/// Create a new non-nullable column definition.
	pub fn new(name: impl Into<String>, data_type: Type) -> Self {
		Self {
			name: name.into(),
			data_type,
			undefined: false,
		}
	}
}

/// Simple trait for user-defined virtual tables.
///
/// Implement this trait when your virtual table can return all data at once.
/// For large datasets that should be streamed, implement [`UserVTableIterator`] instead.
///
/// # Thread Safety
///
/// Implementations must be thread-safe (`Send + Sync`) as the same table instance
/// may be queried concurrently from multiple transactions.
pub trait UserVTable: Clone + Send + Sync + 'static {
	/// Return the column definitions for this table.
	fn vtable(&self) -> Vec<UserVTableColumn>;

	/// Get all data for the table in columnar format.
	///
	/// Returns column-oriented data where each column contains all values
	/// for that column across all rows.
	fn get(&self) -> Columns;
}

/// Pushdown context for advanced virtual table implementations.
///
/// Contains optimization hints that can be used to reduce the amount of data
/// generated by the virtual table.
#[derive(Debug, Clone, Default)]
pub struct UserVTablePushdownContext {
	/// Maximum number of rows to return (if set).
	pub limit: Option<usize>,
	// Future: filters, projections, etc.
}

/// Advanced trait for streaming virtual table implementations.
///
/// Implement this trait when your virtual table needs to:
/// - Stream large datasets in batches
/// - Take advantage of pushdown optimizations (limit, filters)
///
/// # Thread Safety
///
/// Unlike [`UserVTable`], implementations of this trait are instantiated
/// fresh for each query. The factory creates a new instance per query execution.
pub trait UserVTableIterator: Send + Sync + 'static {
	/// Return the column definitions for this table.
	fn columns(&self) -> Vec<UserVTableColumn>;

	/// Initialize the iterator with optional pushdown context.
	///
	/// Called once before iteration begins. Use the pushdown context to
	/// optimize data generation (e.g., limit the number of rows fetched).
	fn initialize(&mut self, ctx: Option<&UserVTablePushdownContext>) -> Result<()>;

	/// Get the next batch of rows.
	///
	/// Returns `Ok(Some(rows))` with the next batch, or `Ok(None)` when exhausted.
	/// Each inner `Vec<Value>` represents one row.
	///
	/// The `batch_size` parameter is a hint for how many rows to return.
	fn next_batch(&mut self, batch_size: usize) -> Result<Option<Vec<Vec<Value>>>>;
}