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}