Skip to main content

toasty_core/driver/operation/
upsert.rs

1use super::{Operation, TypedValue};
2use crate::stmt;
3
4/// Executes a lowered single-row upsert on a non-SQL database driver.
5///
6/// The query engine emits this operation only after verifying the requested
7/// target and branch behavior against [`Capability`](crate::driver::Capability).
8/// [`stmt`](Self::stmt) contains one values row and an
9/// [`stmt::Upsert`](crate::stmt::Upsert) clause whose target has been lowered
10/// from model fields to database columns. Shared mutations retain their
11/// model-declared field defaults so the driver can apply the same value
12/// when it creates an item.
13///
14/// A driver must perform the conflict check and the create, update, or ignore
15/// action atomically. It must not implement this operation as a read followed
16/// by a separate insert or update. An update action returns the stored row. An
17/// ignore action returns one row after an insert and zero rows after the
18/// selected target conflicts.
19///
20/// # Examples
21///
22/// ```ignore
23/// use toasty_core::driver::operation::{Operation, Upsert};
24///
25/// let op = Upsert {
26///     stmt: lowered_insert,
27///     params: typed_params,
28///     ret: Some(return_types),
29/// };
30/// let operation: Operation = op.into();
31/// ```
32#[derive(Debug, Clone)]
33pub struct Upsert {
34    /// The lowered insert statement carrying the conflict target and action.
35    ///
36    /// Literal bind values are replaced with `Expr::Arg(n)`, where `n` indexes
37    /// [`params`](Self::params). The statement's `upsert` field is always
38    /// `Some`, and its target is [`UpsertTarget::Columns`](crate::stmt::UpsertTarget::Columns).
39    pub stmt: stmt::Insert,
40
41    /// Typed bind parameters extracted from [`stmt`](Self::stmt).
42    pub params: Vec<TypedValue>,
43
44    /// Types of the columns returned by the operation, in projection order.
45    ///
46    /// `Some(types)` requires the driver to return the stored row projected to
47    /// these types. `None` requires no returned row.
48    pub ret: Option<Vec<stmt::Type>>,
49}
50
51impl From<Upsert> for Operation {
52    fn from(value: Upsert) -> Self {
53        Self::Upsert(value)
54    }
55}