reifydb_engine/table_virtual/
user.rs

1// Copyright (c) reifydb.com 2025
2// This file is licensed under the AGPL-3.0-or-later, see license.md file
3
4//! User-facing API for defining virtual tables.
5//!
6//! This module provides simplified traits for users to implement custom virtual tables.
7//! Users can choose between two levels of abstraction:
8//!
9//! - [`TableVirtualUser`]: Simple API for tables that can return all rows at once
10//! - [`TableVirtualUserIterator`]: Advanced API for streaming large datasets with optional pushdown
11//!
12//! # Example
13//!
14//! ```ignore
15//! use reifydb_engine::table_virtual::{TableVirtualUser, TableVirtualUserColumnDef};
16//! use reifydb_type::Type;
17//! use reifydb_core::value::Value;
18//!
19//! struct MyApiTable {
20//!     api_client: ApiClient,
21//! }
22//!
23//! impl TableVirtualUser for MyApiTable {
24//!     fn columns(&self) -> Vec<TableVirtualUserColumnDef> {
25//!         vec![
26//!             TableVirtualUserColumnDef::new("id", Type::Uint8),
27//!             TableVirtualUserColumnDef::new("name", Type::Utf8),
28//!         ]
29//!     }
30//!
31//!     fn rows(&self) -> Vec<Vec<Value>> {
32//!         self.api_client.fetch_data()
33//!             .map(|r| vec![Value::Uint8(r.id), Value::Utf8(r.name.into())])
34//!             .collect()
35//!     }
36//! }
37//! ```
38
39use reifydb_type::{Type, Value};
40
41/// Column definition for user virtual tables.
42#[derive(Debug, Clone)]
43pub struct TableVirtualUserColumnDef {
44	/// Column name
45	pub name: String,
46	/// Column data type
47	pub data_type: Type,
48	/// Whether the column allows null values
49	pub nullable: bool,
50}
51
52impl TableVirtualUserColumnDef {
53	/// Create a new non-nullable column definition.
54	pub fn new(name: impl Into<String>, data_type: Type) -> Self {
55		Self {
56			name: name.into(),
57			data_type,
58			nullable: false,
59		}
60	}
61
62	/// Create a new nullable column definition.
63	pub fn nullable(name: impl Into<String>, data_type: Type) -> Self {
64		Self {
65			name: name.into(),
66			data_type,
67			nullable: true,
68		}
69	}
70}
71
72/// Simple trait for user-defined virtual tables.
73///
74/// Implement this trait when your virtual table can return all rows at once.
75/// For large datasets that should be streamed, implement [`TableVirtualUserIterator`] instead.
76///
77/// # Thread Safety
78///
79/// Implementations must be thread-safe (`Send + Sync`) as the same table instance
80/// may be queried concurrently from multiple transactions.
81pub trait TableVirtualUser: Send + Sync + 'static {
82	/// Return the column definitions for this table.
83	fn columns(&self) -> Vec<TableVirtualUserColumnDef>;
84
85	/// Generate all rows for the table.
86	///
87	/// Each inner `Vec<Value>` represents one row, with values in the same order
88	/// as the columns returned by [`columns()`](Self::columns).
89	fn rows(&self) -> Vec<Vec<Value>>;
90}
91
92/// Pushdown context for advanced virtual table implementations.
93///
94/// Contains optimization hints that can be used to reduce the amount of data
95/// generated by the virtual table.
96#[derive(Debug, Clone, Default)]
97pub struct TableVirtualUserPushdownContext {
98	/// Maximum number of rows to return (if set).
99	pub limit: Option<usize>,
100	// Future: filters, projections, etc.
101}
102
103/// Advanced trait for streaming virtual table implementations.
104///
105/// Implement this trait when your virtual table needs to:
106/// - Stream large datasets in batches
107/// - Take advantage of pushdown optimizations (limit, filters)
108///
109/// # Thread Safety
110///
111/// Unlike [`TableVirtualUser`], implementations of this trait are instantiated
112/// fresh for each query. The factory creates a new instance per query execution.
113pub trait TableVirtualUserIterator: Send + 'static {
114	/// Return the column definitions for this table.
115	fn columns(&self) -> Vec<TableVirtualUserColumnDef>;
116
117	/// Initialize the iterator with optional pushdown context.
118	///
119	/// Called once before iteration begins. Use the pushdown context to
120	/// optimize data generation (e.g., limit the number of rows fetched).
121	fn initialize(&mut self, ctx: Option<&TableVirtualUserPushdownContext>) -> crate::Result<()>;
122
123	/// Get the next batch of rows.
124	///
125	/// Returns `Ok(Some(rows))` with the next batch, or `Ok(None)` when exhausted.
126	/// Each inner `Vec<Value>` represents one row.
127	///
128	/// The `batch_size` parameter is a hint for how many rows to return.
129	fn next_batch(&mut self, batch_size: usize) -> crate::Result<Option<Vec<Vec<Value>>>>;
130}