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}