diesel/pg/upsert/
on_conflict_target.rs1use expression::SqlLiteral;
2use pg::Pg;
3use query_builder::*;
4use query_source::Column;
5use result::QueryResult;
6
7pub fn on_constraint(constraint_name: &str) -> OnConstraint {
46 OnConstraint {
47 constraint_name: constraint_name,
48 }
49}
50
51#[doc(hidden)]
52#[derive(Debug, Clone, Copy)]
53pub struct OnConstraint<'a> {
54 constraint_name: &'a str,
55}
56
57pub trait OnConflictTarget<Table>: QueryFragment<Pg> {}
58
59#[doc(hidden)]
60#[derive(Debug, Clone, Copy)]
61pub struct NoConflictTarget;
62
63impl QueryFragment<Pg> for NoConflictTarget {
64 fn walk_ast(&self, _: AstPass<Pg>) -> QueryResult<()> {
65 Ok(())
66 }
67}
68
69impl<Table> OnConflictTarget<Table> for NoConflictTarget {}
70
71#[doc(hidden)]
72#[derive(Debug, Clone, Copy)]
73pub struct ConflictTarget<T>(pub T);
74
75impl<T: Column> QueryFragment<Pg> for ConflictTarget<T> {
76 fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
77 out.push_sql(" (");
78 out.push_identifier(T::NAME)?;
79 out.push_sql(")");
80 Ok(())
81 }
82}
83
84impl<T: Column> OnConflictTarget<T::Table> for ConflictTarget<T> {}
85
86impl<ST> QueryFragment<Pg> for ConflictTarget<SqlLiteral<ST>>
87where
88 SqlLiteral<ST>: QueryFragment<Pg>,
89{
90 fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
91 out.push_sql(" ");
92 self.0.walk_ast(out.reborrow())?;
93 Ok(())
94 }
95}
96
97impl<Tab, ST> OnConflictTarget<Tab> for ConflictTarget<SqlLiteral<ST>> where
98 ConflictTarget<SqlLiteral<ST>>: QueryFragment<Pg>
99{
100}
101
102impl<'a> QueryFragment<Pg> for ConflictTarget<OnConstraint<'a>> {
103 fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
104 out.push_sql(" ON CONSTRAINT ");
105 out.push_identifier(self.0.constraint_name)?;
106 Ok(())
107 }
108}
109
110impl<'a, Table> OnConflictTarget<Table> for ConflictTarget<OnConstraint<'a>> {}
111
112macro_rules! on_conflict_tuples {
113 ($($col:ident),+) => {
114 impl<T, $($col),+> QueryFragment<Pg> for ConflictTarget<(T, $($col),+)> where
115 T: Column,
116 $($col: Column<Table=T::Table>,)+
117 {
118 fn walk_ast(&self, mut out: AstPass<Pg>) -> QueryResult<()> {
119 out.push_sql(" (");
120 out.push_identifier(T::NAME)?;
121 $(
122 out.push_sql(", ");
123 out.push_identifier($col::NAME)?;
124 )+
125 out.push_sql(")");
126 Ok(())
127 }
128 }
129
130 impl<T, $($col),+> OnConflictTarget<T::Table> for ConflictTarget<(T, $($col),+)> where
131 T: Column,
132 $($col: Column<Table=T::Table>,)+
133 {
134 }
135 }
136}
137
138on_conflict_tuples!(U);
139on_conflict_tuples!(U, V);
140on_conflict_tuples!(U, V, W);
141on_conflict_tuples!(U, V, W, X);
142on_conflict_tuples!(U, V, W, X, Y);
143on_conflict_tuples!(U, V, W, X, Y, Z);