diesel::upsert

Struct IncompleteOnConflict

Source
pub struct IncompleteOnConflict<Stmt, Target> { /* private fields */ }
Expand description

A partially constructed ON CONFLICT clause.

Implementations§

Source§

impl<T: QuerySource, U, Op, Ret, Target> IncompleteOnConflict<InsertStatement<T, U, Op, Ret>, Target>

Source

pub fn do_nothing( self, ) -> InsertStatement<T, OnConflictValues<U, Target, DoNothing<T>>, Op, Ret>

Creates a query with ON CONFLICT (target) DO NOTHING

If you want to do nothing when any constraint conflicts, use on_conflict_do_nothing instead. See on_conflict for usage examples.

Source§

impl<Stmt, Target> IncompleteOnConflict<Stmt, Target>

Source

pub fn do_update(self) -> IncompleteDoUpdate<Stmt, Target>

Used to create a query in the form ON CONFLICT (...) DO UPDATE ... [WHERE ...]

Call .set on the result of this function with the changes you want to apply. The argument to set can be anything that implements AsChangeset (e.g. anything you could pass to set on a normal update statement).

Note: When inserting more than one row at a time, this query can still fail if the rows being inserted conflict with each other.

Some backends (PostgreSQL) support WHERE clause is used to limit the rows actually updated. For PostgreSQL you can use the .filter() method to add conditions like this.

§Examples
§Set specific value on conflict

PostgreSQL/SQLite:

let user = User { id: 1, name: "Pascal" };
let user2 = User { id: 1, name: "Sean" };

assert_eq!(Ok(1), diesel::insert_into(users).values(&user).execute(conn));

let insert_count = diesel::insert_into(users)
    .values(&user2)
    .on_conflict(id)
    .do_update()
    .set(name.eq("I DONT KNOW ANYMORE"))
    .execute(conn);
assert_eq!(Ok(1), insert_count);
assert_eq!(Ok(2), insert_count);

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "I DONT KNOW ANYMORE".to_string())]), users_in_db);

MySQL:

let user = User { id: 1, name: "Pascal" };
let user2 = User { id: 1, name: "Sean" };

assert_eq!(Ok(1), diesel::insert_into(users).values(&user).execute(conn));

diesel::insert_into(users)
    .values(&user2)
    .on_conflict(diesel::dsl::DuplicatedKeys)
    .do_update()
    .set(name.eq("I DONT KNOW ANYMORE"))
    .execute(conn)?;

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "I DONT KNOW ANYMORE".to_string())]), users_in_db);
§Set AsChangeset struct on conflict

PostgreSQL & SQLite:

let user = User { id: 1, name: "Pascal" };
let user2 = User { id: 1, name: "Sean" };

assert_eq!(Ok(1), diesel::insert_into(users).values(&user).execute(conn));

let insert_count = diesel::insert_into(users)
    .values(&user2)
    .on_conflict(id)
    .do_update()
    .set(&user2)
    .execute(conn);
assert_eq!(Ok(1), insert_count);

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "Sean".to_string())]), users_in_db);

MySQL:


let user = User { id: 1, name: "Pascal" };
let user2 = User { id: 1, name: "Sean" };

assert_eq!(Ok(1), diesel::insert_into(users).values(&user).execute(conn));

diesel::insert_into(users)
    .values(&user2)
    .on_conflict(diesel::dsl::DuplicatedKeys)
    .do_update()
    .set(&user2)
    .execute(conn)?;

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "Sean".to_string())]), users_in_db);
§Use excluded to get the rejected value
use diesel::upsert::excluded;

let user = User { id: 1, name: "Pascal" };
let user2 = User { id: 1, name: "Sean" };
let user3 = User { id: 2, name: "Tess" };

assert_eq!(Ok(1), diesel::insert_into(users).values(&user).execute(conn));

#[cfg(feature = "postgres")]
let insert_count = diesel::insert_into(users)
    .values(&vec![user2, user3])
    .on_conflict(id)
    .do_update()
    .set(name.eq(excluded(name)))
    .execute(conn);
assert_eq!(Ok(2), insert_count);

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "Sean".to_string()), (2, "Tess".to_string())]), users_in_db);
§Use .filter()method to limit the rows actually updated
use self::users::dsl::*;
let user = User { id: 1, name: "Pascal" };
let user2 = User { id: 1, name: "Sean" };

assert_eq!(Ok(1), diesel::insert_into(users).values(&user).execute(conn));

let insert_count = diesel::insert_into(users)
    .values(&user2)
    .on_conflict(id)
    .do_update()
    .set(&user2)
    .filter(id.ge(5))
    .execute(conn);
assert_eq!(Ok(0), insert_count);

let users_in_db = users.load(conn);
assert_eq!(Ok(vec![(1, "Pascal".to_string())]), users_in_db);

Trait Implementations§

Source§

impl<Stmt: Clone, Target: Clone> Clone for IncompleteOnConflict<Stmt, Target>

Source§

fn clone(&self) -> IncompleteOnConflict<Stmt, Target>

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<Stmt: Debug, Target: Debug> Debug for IncompleteOnConflict<Stmt, Target>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<Stmt, T, P> DecoratableTarget<P> for IncompleteOnConflict<Stmt, T>

Source§

type FilterOutput = IncompleteOnConflict<Stmt, <T as DecoratableTarget<P>>::FilterOutput>

Output type of filter_target operation
Source§

fn filter_target(self, predicate: P) -> Self::FilterOutput

equivalent to filter of FilterDsl but aimed at conflict targets
Source§

impl<Stmt: Copy, Target: Copy> Copy for IncompleteOnConflict<Stmt, Target>

Auto Trait Implementations§

§

impl<Stmt, Target> Freeze for IncompleteOnConflict<Stmt, Target>
where Stmt: Freeze, Target: Freeze,

§

impl<Stmt, Target> RefUnwindSafe for IncompleteOnConflict<Stmt, Target>
where Stmt: RefUnwindSafe, Target: RefUnwindSafe,

§

impl<Stmt, Target> Send for IncompleteOnConflict<Stmt, Target>
where Stmt: Send, Target: Send,

§

impl<Stmt, Target> Sync for IncompleteOnConflict<Stmt, Target>
where Stmt: Sync, Target: Sync,

§

impl<Stmt, Target> Unpin for IncompleteOnConflict<Stmt, Target>
where Stmt: Unpin, Target: Unpin,

§

impl<Stmt, Target> UnwindSafe for IncompleteOnConflict<Stmt, Target>
where Stmt: UnwindSafe, Target: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoSql for T

Source§

fn into_sql<T>(self) -> AsExprOf<Self, T>

Convert self to an expression for Diesel’s query builder. Read more
Source§

fn as_sql<'a, T>(&'a self) -> AsExprOf<&'a Self, T>
where &'a Self: AsExpression<T>, T: SqlType + TypedExpressionType,

Convert &self to an expression for Diesel’s query builder. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> MaybeSendSync for T