11pub use super :: on_conflict_clause:: * ;
2+ pub use super :: on_conflict_target:: * ;
23
34/// Adds extension methods related to PG upsert
45pub trait OnConflictExtension {
@@ -12,21 +13,7 @@ pub trait OnConflictExtension {
1213 /// ```rust
1314 /// # #[macro_use] extern crate diesel;
1415 /// # #[macro_use] extern crate diesel_codegen;
15- /// # include!("src/doctest_setup.rs");
16- /// #
17- /// # table! {
18- /// # users {
19- /// # id -> Integer,
20- /// # name -> VarChar,
21- /// # }
22- /// # }
23- /// #
24- /// # #[derive(Clone, Copy, Insertable)]
25- /// # #[table_name="users"]
26- /// # struct User<'a> {
27- /// # id: i32,
28- /// # name: &'a str,
29- /// # }
16+ /// # include!("src/pg/upsert/on_conflict_docs_setup.rs");
3017 /// #
3118 /// # fn main() {
3219 /// # use self::users::dsl::*;
@@ -51,21 +38,7 @@ pub trait OnConflictExtension {
5138 /// ```rust
5239 /// # #[macro_use] extern crate diesel;
5340 /// # #[macro_use] extern crate diesel_codegen;
54- /// # include!("src/doctest_setup.rs");
55- /// #
56- /// # table! {
57- /// # users {
58- /// # id -> Integer,
59- /// # name -> VarChar,
60- /// # }
61- /// # }
62- /// #
63- /// # #[derive(Clone, Copy, Insertable)]
64- /// # #[table_name="users"]
65- /// # struct User<'a> {
66- /// # id: i32,
67- /// # name: &'a str,
68- /// # }
41+ /// # include!("src/pg/upsert/on_conflict_docs_setup.rs");
6942 /// #
7043 /// # fn main() {
7144 /// # use self::users::dsl::*;
@@ -86,12 +59,86 @@ pub trait OnConflictExtension {
8659 /// ```rust
8760 /// # #[macro_use] extern crate diesel;
8861 /// # #[macro_use] extern crate diesel_codegen;
62+ /// # include!("src/pg/upsert/on_conflict_docs_setup.rs");
63+ /// #
64+ /// # fn main() {
65+ /// # use self::users::dsl::*;
66+ /// use self::diesel::pg::upsert::*;
67+ ///
68+ /// # let conn = establish_connection();
69+ /// # conn.execute("TRUNCATE TABLE users").unwrap();
70+ /// let user = User { id: 1, name: "Sean", };
71+ ///
72+ /// let new_users: &[User] = &[user, user];
73+ /// let inserted_row_count = diesel::insert(&new_users.on_conflict_do_nothing())
74+ /// .into(users).execute(&conn);
75+ /// assert_eq!(Ok(1), inserted_row_count);
76+ /// # }
77+ /// ```
78+ fn on_conflict_do_nothing ( & self ) -> OnConflictDoNothing < & Self > {
79+ OnConflictDoNothing :: new ( self )
80+ }
81+
82+ /// Adds an `ON CONFLICT` to the insert statement, performing the action
83+ /// specified by `Action` if a conflict occurs for `Target`.
84+ ///
85+ /// `Target` can be one of:
86+ ///
87+ /// - A column
88+ /// - A tuple of columns
89+ /// - [`on_constraint("constraint_name")`](fn.on_constraint.html)
90+ ///
91+ /// `Action` can be one of:
92+ ///
93+ /// - [`do_nothing()`](fn.do_nothing.html)
94+ /// - [`do_update()`]
95+ ///
96+ /// # Examples
97+ ///
98+ /// ### Specifying a column as the target
99+ ///
100+ /// ```rust
101+ /// # #[macro_use] extern crate diesel;
102+ /// # #[macro_use] extern crate diesel_codegen;
103+ /// # include!("src/pg/upsert/on_conflict_docs_setup.rs");
104+ /// #
105+ /// # fn main() {
106+ /// # use self::users::dsl::*;
107+ /// use self::diesel::pg::upsert::*;
108+ ///
109+ /// # let conn = establish_connection();
110+ /// # conn.execute("TRUNCATE TABLE users").unwrap();
111+ /// conn.execute("CREATE UNIQUE INDEX users_name ON users (name)").unwrap();
112+ /// let user = User { id: 1, name: "Sean", };
113+ /// let same_name_different_id = User { id: 2, name: "Sean" };
114+ /// let same_id_different_name = User { id: 1, name: "Pascal" };
115+ ///
116+ /// assert_eq!(Ok(1), diesel::insert(&user).into(users).execute(&conn));
117+ ///
118+ /// let inserted_row_count = diesel::insert(
119+ /// &same_name_different_id.on_conflict(name, do_nothing())
120+ /// ).into(users).execute(&conn);
121+ /// assert_eq!(Ok(0), inserted_row_count);
122+ ///
123+ /// let pk_conflict_result = diesel::insert(
124+ /// &same_id_different_name.on_conflict(name, do_nothing())
125+ /// ).into(users).execute(&conn);
126+ /// assert!(pk_conflict_result.is_err());
127+ /// # }
128+ /// ```
129+ ///
130+ /// ### Specifying multiple columns as the target
131+ ///
132+ /// ```rust
133+ /// # #[macro_use] extern crate diesel;
134+ /// # #[macro_use] extern crate diesel_codegen;
89135 /// # include!("src/doctest_setup.rs");
90136 /// #
91137 /// # table! {
92138 /// # users {
93139 /// # id -> Integer,
94140 /// # name -> VarChar,
141+ /// # hair_color -> VarChar,
95142 /// # }
96143 /// # }
97144 /// #
@@ -100,24 +147,41 @@ pub trait OnConflictExtension {
100147 /// # struct User<'a> {
101148 /// # id: i32,
102149 /// # name: &'a str,
150+ /// # hair_color: &'a str,
103151 /// # }
104152 /// #
105153 /// # fn main() {
106154 /// # use self::users::dsl::*;
107155 /// use self::diesel::pg::upsert::*;
108156 ///
109157 /// # let conn = establish_connection();
110- /// # conn.execute("TRUNCATE TABLE users").unwrap();
111- /// let user = User { id: 1, name: "Sean", };
158+ /// # conn.execute("DROP TABLE users").unwrap();
159+ /// # conn.execute("CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT, hair_color TEXT)").unwrap();
160+ /// conn.execute("CREATE UNIQUE INDEX users_name_hair_color ON users (name, hair_color)").unwrap();
161+ /// let user = User { id: 1, name: "Sean", hair_color: "black" };
162+ /// let same_name_different_hair_color = User { id: 2, name: "Sean", hair_color: "brown" };
163+ /// let same_same_name_same_hair_color = User { id: 3, name: "Sean", hair_color: "black" };
112164 ///
113- /// let new_users: &[User] = &[user, user];
114- /// let inserted_row_count = diesel::insert(&new_users.on_conflict_do_nothing())
115- /// .into(users).execute(&conn);
165+ /// assert_eq!(Ok(1), diesel::insert(&user).into(users).execute(&conn));
166+ ///
167+ /// let inserted_row_count = diesel::insert(
168+ /// &same_name_different_hair_color.on_conflict((name, hair_color), do_nothing())
169+ /// ).into(users).execute(&conn);
116170 /// assert_eq!(Ok(1), inserted_row_count);
171+ ///
172+ /// let inserted_row_count = diesel::insert(
173+ /// &same_same_name_same_hair_color.on_conflict((name, hair_color), do_nothing())
174+ /// ).into(users).execute(&conn);
175+ /// assert_eq!(Ok(0), inserted_row_count);
117176 /// # }
118177 /// ```
119- fn on_conflict_do_nothing ( & self ) -> OnConflictDoNothing < & Self > {
120- OnConflictDoNothing :: new ( self )
178+ ///
179+ /// See the documentation for [`on_constraint`](fn.on_constraint.html) and [`do_update`] for
180+ /// more examples.
181+ fn on_conflict < Target , Action > ( & self , target : Target , action : Action )
182+ -> OnConflict < & Self , ConflictTarget < Target > , Action >
183+ {
184+ OnConflict :: new ( self , ConflictTarget ( target) , action)
121185 }
122186}
123187
0 commit comments