1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::query_builder::insert_statement::{BatchInsert, InsertFromSelect};
#[cfg(feature = "sqlite")]
use crate::query_builder::where_clause::{BoxedWhereClause, WhereClause};
#[cfg(any(feature = "sqlite", feature = "postgres"))]
use crate::query_builder::{AstPass, QueryFragment};
use crate::query_builder::{BoxedSelectStatement, Query, SelectStatement, ValuesClause};
#[cfg(any(feature = "sqlite", feature = "postgres"))]
use crate::result::QueryResult;
pub trait IntoConflictValueClause {
type ValueClause;
fn into_value_clause(self) -> Self::ValueClause;
}
#[derive(Debug, Clone, Copy)]
pub struct OnConflictSelectWrapper<S>(S);
impl<Q> Query for OnConflictSelectWrapper<Q>
where
Q: Query,
{
type SqlType = Q::SqlType;
}
#[cfg(feature = "postgres")]
impl<S> QueryFragment<crate::pg::Pg> for OnConflictSelectWrapper<S>
where
S: QueryFragment<crate::pg::Pg>,
{
fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, crate::pg::Pg>) -> QueryResult<()> {
self.0.walk_ast(out)
}
}
#[cfg(feature = "sqlite")]
impl<F, S, D, W, O, LOf, G, H, LC> QueryFragment<crate::sqlite::Sqlite>
for OnConflictSelectWrapper<SelectStatement<F, S, D, WhereClause<W>, O, LOf, G, H, LC>>
where
SelectStatement<F, S, D, WhereClause<W>, O, LOf, G, H, LC>:
QueryFragment<crate::sqlite::Sqlite>,
{
fn walk_ast<'b>(&'b self, out: AstPass<'_, 'b, crate::sqlite::Sqlite>) -> QueryResult<()> {
self.0.walk_ast(out)
}
}
#[cfg(feature = "sqlite")]
impl<'a, ST, QS, GB> QueryFragment<crate::sqlite::Sqlite>
for OnConflictSelectWrapper<BoxedSelectStatement<'a, ST, QS, crate::sqlite::Sqlite, GB>>
where
BoxedSelectStatement<'a, ST, QS, crate::sqlite::Sqlite, GB>:
QueryFragment<crate::sqlite::Sqlite>,
QS: QueryFragment<crate::sqlite::Sqlite>,
{
fn walk_ast<'b>(&'b self, pass: AstPass<'_, 'b, crate::sqlite::Sqlite>) -> QueryResult<()> {
self.0.build_query(pass, |where_clause, mut pass| {
match where_clause {
BoxedWhereClause::None => pass.push_sql(" WHERE 1=1 "),
w => w.walk_ast(pass.reborrow())?,
}
Ok(())
})
}
}
impl<Inner, Tab> IntoConflictValueClause for ValuesClause<Inner, Tab> {
type ValueClause = Self;
fn into_value_clause(self) -> Self::ValueClause {
self
}
}
impl<V, Tab, QId, const STATIC_QUERY_ID: bool> IntoConflictValueClause
for BatchInsert<V, Tab, QId, STATIC_QUERY_ID>
{
type ValueClause = Self;
fn into_value_clause(self) -> Self::ValueClause {
self
}
}
impl<F, S, D, W, O, LOf, G, H, LC, Columns> IntoConflictValueClause
for InsertFromSelect<SelectStatement<F, S, D, W, O, LOf, G, H, LC>, Columns>
{
type ValueClause = InsertFromSelect<
OnConflictSelectWrapper<SelectStatement<F, S, D, W, O, LOf, G, H, LC>>,
Columns,
>;
fn into_value_clause(self) -> Self::ValueClause {
let InsertFromSelect { columns, query } = self;
InsertFromSelect {
query: OnConflictSelectWrapper(query),
columns,
}
}
}
impl<'a, ST, QS, DB, GB, Columns> IntoConflictValueClause
for InsertFromSelect<BoxedSelectStatement<'a, ST, QS, DB, GB>, Columns>
{
type ValueClause = InsertFromSelect<
OnConflictSelectWrapper<BoxedSelectStatement<'a, ST, QS, DB, GB>>,
Columns,
>;
fn into_value_clause(self) -> Self::ValueClause {
let InsertFromSelect { columns, query } = self;
InsertFromSelect {
query: OnConflictSelectWrapper(query),
columns,
}
}
}