pub trait TableSource:
DataSource
+ Clone
+ 'static {
type Column<Type>: ColumnLike<Type> + Clone
where Type: ColumnType;
type AnyType: ColumnType;
type Value: Clone + Send + Sync + 'static;
type Id: Send + Sync + Clone + Hash + Eq + 'static;
type Condition: Clone + Send + Sync + 'static;
Show 22 methods
// Required methods
fn create_column<Type: ColumnType>(&self, name: &str) -> Self::Column<Type>;
fn to_any_column<Type: ColumnType>(
&self,
column: Self::Column<Type>,
) -> Self::Column<Self::AnyType>;
fn convert_any_column<Type: ColumnType>(
&self,
any_column: Self::Column<Self::AnyType>,
) -> Option<Self::Column<Type>>;
fn expr(
&self,
template: impl Into<String>,
parameters: Vec<ExpressiveEnum<Self::Value>>,
) -> Expression<Self::Value>;
fn search_table_condition<E>(
&self,
table: &Table<Self, E>,
search_value: &str,
) -> Self::Condition
where E: Entity<Self::Value>,
Self: Sized;
fn list_table_values<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<IndexMap<Self::Id, Record<Self::Value>>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_table_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn get_table_some_value<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<Option<(Self::Id, Record<Self::Value>)>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_table_count<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<i64>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn get_table_sum<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn get_table_max<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn get_table_min<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn insert_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
record: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn replace_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
record: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn patch_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
partial: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait;
fn delete_table_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn delete_table_all_values<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
fn insert_table_return_id_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
record: &'life2 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Self::Id>> + Send + 'async_trait>>
where E: Entity<Self::Value> + 'async_trait,
Self: Sized + 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait;
fn related_in_condition<SourceE: Entity<Self::Value> + 'static>(
&self,
target_field: &str,
source_table: &Table<Self, SourceE>,
source_column: &str,
) -> Self::Condition
where Self: Sized;
fn column_table_values_expr<'a, E, Type: ColumnType>(
&'a self,
table: &Table<Self, E>,
column: &Self::Column<Type>,
) -> AssociatedExpression<'a, Self, Self::Value, Vec<Type>>
where E: Entity<Self::Value> + 'static,
Self: ExprDataSource<Self::Value> + Sized;
// Provided methods
fn stream_table_values<'a, E>(
&'a self,
table: &Table<Self, E>,
) -> Pin<Box<dyn Stream<Item = Result<(Self::Id, Record<Self::Value>)>> + Send + 'a>>
where E: Entity<Self::Value> + 'a,
Self: Sized { ... }
fn related_correlated_condition(
&self,
target_table: &str,
target_field: &str,
source_table: &str,
source_column: &str,
) -> Self::Condition { ... }
}Expand description
Trait for table data sources that defines column type separate from execution TableSource represents a data source that can create and manage tables
Required Associated Types§
type Column<Type>: ColumnLike<Type> + Clone where Type: ColumnType
type AnyType: ColumnType
type Value: Clone + Send + Sync + 'static
type Id: Send + Sync + Clone + Hash + Eq + 'static
Required Methods§
Sourcefn create_column<Type: ColumnType>(&self, name: &str) -> Self::Column<Type>
fn create_column<Type: ColumnType>(&self, name: &str) -> Self::Column<Type>
Create a new column with the given name
Sourcefn to_any_column<Type: ColumnType>(
&self,
column: Self::Column<Type>,
) -> Self::Column<Self::AnyType>
fn to_any_column<Type: ColumnType>( &self, column: Self::Column<Type>, ) -> Self::Column<Self::AnyType>
Convert a typed column to type-erased column
Sourcefn convert_any_column<Type: ColumnType>(
&self,
any_column: Self::Column<Self::AnyType>,
) -> Option<Self::Column<Type>>
fn convert_any_column<Type: ColumnType>( &self, any_column: Self::Column<Self::AnyType>, ) -> Option<Self::Column<Type>>
Attempt to convert a type-erased column back to typed column
Sourcefn expr(
&self,
template: impl Into<String>,
parameters: Vec<ExpressiveEnum<Self::Value>>,
) -> Expression<Self::Value>
fn expr( &self, template: impl Into<String>, parameters: Vec<ExpressiveEnum<Self::Value>>, ) -> Expression<Self::Value>
Create an expression from a template and parameters, similar to Expression::new
Sourcefn search_table_condition<E>(
&self,
table: &Table<Self, E>,
search_value: &str,
) -> Self::Condition
fn search_table_condition<E>( &self, table: &Table<Self, E>, search_value: &str, ) -> Self::Condition
Create a search condition for a table (e.g., searches across searchable fields)
Different vendors implement search differently:
- SQL:
field LIKE '%value%'(returns Expression) - SurrealDB:
field CONTAINS 'value'(returns Expression) - MongoDB:
{ field: { $regex: 'value' } }(returns MongoCondition)
The implementation should search across appropriate fields in the table.
Sourcefn list_table_values<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<IndexMap<Self::Id, Record<Self::Value>>>> + Send + 'async_trait>>
fn list_table_values<'life0, 'life1, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, ) -> Pin<Box<dyn Future<Output = Result<IndexMap<Self::Id, Record<Self::Value>>>> + Send + 'async_trait>>
Get all data from a table as Record values with IDs (for ReadableValueSet implementation)
Sourcefn get_table_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
fn get_table_value<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, ) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
Get a single record by ID as Record value (for ReadableValueSet implementation)
Sourcefn get_table_some_value<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<Option<(Self::Id, Record<Self::Value>)>>> + Send + 'async_trait>>
fn get_table_some_value<'life0, 'life1, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, ) -> Pin<Box<dyn Future<Output = Result<Option<(Self::Id, Record<Self::Value>)>>> + Send + 'async_trait>>
Get some data from a table as Record value with ID (for ReadableValueSet implementation)
Sourcefn get_table_count<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<i64>> + Send + 'async_trait>>
fn get_table_count<'life0, 'life1, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, ) -> Pin<Box<dyn Future<Output = Result<i64>> + Send + 'async_trait>>
Get count of records in the table
Sourcefn get_table_sum<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
fn get_table_sum<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, column: &'life2 Self::Column<Self::AnyType>, ) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
Get sum of a column in the table (returns native value type)
Sourcefn get_table_max<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
fn get_table_max<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, column: &'life2 Self::Column<Self::AnyType>, ) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
Get maximum value of a column in the table (returns native value type)
Sourcefn get_table_min<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
column: &'life2 Self::Column<Self::AnyType>,
) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
fn get_table_min<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, column: &'life2 Self::Column<Self::AnyType>, ) -> Pin<Box<dyn Future<Output = Result<Self::Value>> + Send + 'async_trait>>
Get minimum value of a column in the table (returns native value type)
Sourcefn insert_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
record: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
fn insert_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, record: &'life3 Record<Self::Value>, ) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
Insert a record as Record value (for WritableValueSet implementation)
Sourcefn replace_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
record: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
fn replace_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, record: &'life3 Record<Self::Value>, ) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
Replace a record as Record value (for WritableValueSet implementation)
Sourcefn patch_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
partial: &'life3 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
fn patch_table_value<'life0, 'life1, 'life2, 'life3, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, partial: &'life3 Record<Self::Value>, ) -> Pin<Box<dyn Future<Output = Result<Record<Self::Value>>> + Send + 'async_trait>>
Patch a record as Record value (for WritableValueSet implementation)
Sourcefn delete_table_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
id: &'life2 Self::Id,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
fn delete_table_value<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, id: &'life2 Self::Id, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
Delete a record by ID (for WritableValueSet implementation)
Sourcefn delete_table_all_values<'life0, 'life1, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
fn delete_table_all_values<'life0, 'life1, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, ) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'async_trait>>
Delete all records (for WritableValueSet implementation)
Sourcefn insert_table_return_id_value<'life0, 'life1, 'life2, 'async_trait, E>(
&'life0 self,
table: &'life1 Table<Self, E>,
record: &'life2 Record<Self::Value>,
) -> Pin<Box<dyn Future<Output = Result<Self::Id>> + Send + 'async_trait>>
fn insert_table_return_id_value<'life0, 'life1, 'life2, 'async_trait, E>( &'life0 self, table: &'life1 Table<Self, E>, record: &'life2 Record<Self::Value>, ) -> Pin<Box<dyn Future<Output = Result<Self::Id>> + Send + 'async_trait>>
Insert a record and return generated ID (for InsertableValueSet implementation)
Build a condition for “target_field IN (values of source_column from source_table)”.
Used by the relationship traversal system (get_ref_as) to filter
a target table by foreign key values from a source table.
Each backend implements this natively:
- SQL backends build a subquery:
"id" IN (SELECT "bakery_id" FROM "client" WHERE ...) - MongoDB builds a deferred
{ field: { "$in": [...] } }document - CSV fetches values in memory and builds an IN condition
Sourcefn column_table_values_expr<'a, E, Type: ColumnType>(
&'a self,
table: &Table<Self, E>,
column: &Self::Column<Type>,
) -> AssociatedExpression<'a, Self, Self::Value, Vec<Type>>
fn column_table_values_expr<'a, E, Type: ColumnType>( &'a self, table: &Table<Self, E>, column: &Self::Column<Type>, ) -> AssociatedExpression<'a, Self, Self::Value, Vec<Type>>
Return an associated expression that, when resolved, yields all values of the given typed column from this table (respecting current conditions).
For query-language backends, this can be a subquery expression.
For simple backends (CSV), this uses a DeferredFn that loads data
and extracts the column values at execution time.
The returned AssociatedExpression can be:
- Executed directly:
.get().await -> Result<Vec<Type>> - Composed into expressions: used via
Expressivetrait inin_()conditions
let fk_col = source.get_column::<String>("bakery_id").unwrap();
let fk_values = source.data_source().column_table_values_expr(&source, &fk_col);
// Execute: let ids = fk_values.get().await?;
// Or compose: target.add_condition(target["id"].in_((fk_values)));Provided Methods§
Sourcefn stream_table_values<'a, E>(
&'a self,
table: &Table<Self, E>,
) -> Pin<Box<dyn Stream<Item = Result<(Self::Id, Record<Self::Value>)>> + Send + 'a>>
fn stream_table_values<'a, E>( &'a self, table: &Table<Self, E>, ) -> Pin<Box<dyn Stream<Item = Result<(Self::Id, Record<Self::Value>)>> + Send + 'a>>
Stream all records from a table as (Id, Record) pairs.
Default implementation wraps list_table_values into a stream.
Backends with native streaming (e.g. REST APIs with pagination)
can override this to yield records incrementally.
Build a correlated condition: target_table.target_field = source_table.source_column.
Used by get_subquery_as for embedding correlated subqueries inside SELECT
expressions (e.g. (SELECT COUNT(*) FROM order WHERE order.client_id = client.id)).
SQL backends produce table-qualified equality; non-SQL backends may not support correlated subqueries and should leave the default (which panics).
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.