1use crate::pg::Pg;
2use crate::query_builder::nodes::StaticQueryFragment;
3use crate::query_builder::ColumnList;
4use crate::query_builder::QueryFragment;
5use crate::sql_types::SqlType;
6use crate::Expression;
7use crate::{Column, Table};
8
9pub(crate) mod copy_from;
10pub(crate) mod copy_to;
11
12#[cfg(feature = "postgres")]
13pub(crate) use self::copy_from::{CopyFromExpression, InternalCopyFromQuery};
14#[cfg(feature = "postgres")]
15pub(crate) use self::copy_to::CopyToCommand;
16
17pub use self::copy_from::{CopyFromQuery, CopyHeader, ExecuteCopyFromDsl};
18pub use self::copy_to::CopyToQuery;
19
20const COPY_MAGIC_HEADER: [u8; 11] = [
21 0x50, 0x47, 0x43, 0x4F, 0x50, 0x59, 0x0A, 0xFF, 0x0D, 0x0A, 0x00,
22];
23
24)]
30pub enum CopyFormat {
31 #[default]
35 Text,
36 Csv,
38 Binary,
40}
41
42impl CopyFormat {
43 fn to_sql_format(self) -> &'static str {
44 match self {
45 CopyFormat::Text => "text",
46 CopyFormat::Csv => "csv",
47 CopyFormat::Binary => "binary",
48 }
49 }
50}
51
52#[derive(#[automatically_derived]
impl ::core::default::Default for CommonOptions {
#[inline]
fn default() -> CommonOptions {
CommonOptions {
format: ::core::default::Default::default(),
freeze: ::core::default::Default::default(),
delimiter: ::core::default::Default::default(),
null: ::core::default::Default::default(),
quote: ::core::default::Default::default(),
escape: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::fmt::Debug for CommonOptions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["format", "freeze", "delimiter", "null", "quote", "escape"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.format, &self.freeze, &self.delimiter, &self.null,
&self.quote, &&self.escape];
::core::fmt::Formatter::debug_struct_fields_finish(f, "CommonOptions",
names, values)
}
}Debug)]
53struct CommonOptions {
54 format: Option<CopyFormat>,
55 freeze: Option<bool>,
56 delimiter: Option<char>,
57 null: Option<String>,
58 quote: Option<char>,
59 escape: Option<char>,
60}
61
62impl CommonOptions {
63 fn any_set(&self) -> bool {
64 self.format.is_some()
65 || self.freeze.is_some()
66 || self.delimiter.is_some()
67 || self.null.is_some()
68 || self.quote.is_some()
69 || self.escape.is_some()
70 }
71
72 fn walk_ast<'b>(
73 &'b self,
74 mut pass: crate::query_builder::AstPass<'_, 'b, Pg>,
75 comma: &mut &'static str,
76 ) {
77 if let Some(format) = self.format {
78 pass.push_sql(comma);
79 *comma = ", ";
80 pass.push_sql("FORMAT ");
81 pass.push_sql(format.to_sql_format());
82 }
83 if let Some(freeze) = self.freeze {
84 pass.push_sql(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{1}FREEZE {0}", freeze as u8,
comma))
})format!("{comma}FREEZE {}", freeze as u8));
85 *comma = ", ";
86 }
87 if let Some(delimiter) = self.delimiter {
88 pass.push_sql(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}DELIMITER \'{1}\'", comma,
delimiter))
})format!("{comma}DELIMITER '{delimiter}'"));
89 *comma = ", ";
90 }
91 if let Some(ref null) = self.null {
92 pass.push_sql(comma);
93 *comma = ", ";
94 pass.push_sql("NULL '");
95 pass.push_sql(null);
97 pass.push_sql("'");
98 }
99 if let Some(quote) = self.quote {
100 pass.push_sql(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}QUOTE \'{1}\'", comma, quote))
})format!("{comma}QUOTE '{quote}'"));
101 *comma = ", ";
102 }
103 if let Some(escape) = self.escape {
104 pass.push_sql(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}ESCAPE \'{1}\'", comma, escape))
})format!("{comma}ESCAPE '{escape}'"));
105 *comma = ", ";
106 }
107 }
108}
109
110pub trait CopyTarget {
114 type Table: Table;
116 type SqlType: SqlType;
118
119 #[doc(hidden)]
120 fn walk_target(pass: crate::query_builder::AstPass<'_, '_, Pg>) -> crate::QueryResult<()>;
121}
122
123impl<T> CopyTarget for T
124where
125 T: Table + StaticQueryFragment,
126 T::SqlType: SqlType,
127 T::AllColumns: ColumnList,
128 T::Component: QueryFragment<Pg>,
129{
130 type Table = Self;
131 type SqlType = T::SqlType;
132
133 fn walk_target(mut pass: crate::query_builder::AstPass<'_, '_, Pg>) -> crate::QueryResult<()> {
134 T::STATIC_COMPONENT.walk_ast(pass.reborrow())?;
135 pass.push_sql("(");
136 T::all_columns().walk_ast(pass.reborrow())?;
137 pass.push_sql(")");
138 Ok(())
139 }
140}
141
142macro_rules! copy_target_for_columns {
143 ($(
144 $Tuple:tt {
145 $(($idx:tt) -> $T:ident, $ST:ident, $TT:ident,)+
146 }
147 )+) => {
148 $(
149 impl<T, $($ST,)*> CopyTarget for ($($ST,)*)
150 where
151 $($ST: Column<Table = T> + Default,)*
152 ($(<$ST as Expression>::SqlType,)*): SqlType,
153 T: Table + StaticQueryFragment,
154 T::Component: QueryFragment<Pg>,
155 Self: ColumnList,
156 {
157 type Table = T;
158 type SqlType = crate::dsl::SqlTypeOf<Self>;
159
160 fn walk_target(
161 mut pass: crate::query_builder::AstPass<'_, '_, Pg>,
162 ) -> crate::QueryResult<()> {
163 T::STATIC_COMPONENT.walk_ast(pass.reborrow())?;
164 pass.push_sql("(");
165 <Self as ColumnList>::walk_ast(&($($ST::default(),)*), pass.reborrow())?;
166 pass.push_sql(")");
167 Ok(())
168 }
169 }
170 )*
171 }
172}
173
174impl<T, ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10, ST11, ST12,
ST13, ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22, ST23, ST24,
ST25, ST26, ST27, ST28, ST29, ST30, ST31> CopyTarget for
(ST, ST1, ST2, ST3, ST4, ST5, ST6, ST7, ST8, ST9, ST10, ST11, ST12, ST13,
ST14, ST15, ST16, ST17, ST18, ST19, ST20, ST21, ST22, ST23, ST24, ST25,
ST26, ST27, ST28, ST29, ST30, ST31) where ST: Column<Table = T> + Default,
ST1: Column<Table = T> + Default, ST2: Column<Table = T> + Default,
ST3: Column<Table = T> + Default, ST4: Column<Table = T> + Default,
ST5: Column<Table = T> + Default, ST6: Column<Table = T> + Default,
ST7: Column<Table = T> + Default, ST8: Column<Table = T> + Default,
ST9: Column<Table = T> + Default, ST10: Column<Table = T> + Default,
ST11: Column<Table = T> + Default, ST12: Column<Table = T> + Default,
ST13: Column<Table = T> + Default, ST14: Column<Table = T> + Default,
ST15: Column<Table = T> + Default, ST16: Column<Table = T> + Default,
ST17: Column<Table = T> + Default, ST18: Column<Table = T> + Default,
ST19: Column<Table = T> + Default, ST20: Column<Table = T> + Default,
ST21: Column<Table = T> + Default, ST22: Column<Table = T> + Default,
ST23: Column<Table = T> + Default, ST24: Column<Table = T> + Default,
ST25: Column<Table = T> + Default, ST26: Column<Table = T> + Default,
ST27: Column<Table = T> + Default, ST28: Column<Table = T> + Default,
ST29: Column<Table = T> + Default, ST30: Column<Table = T> + Default,
ST31: Column<Table = T> + Default,
(<ST as Expression>::SqlType, <ST1 as Expression>::SqlType,
<ST2 as Expression>::SqlType, <ST3 as Expression>::SqlType,
<ST4 as Expression>::SqlType, <ST5 as Expression>::SqlType,
<ST6 as Expression>::SqlType, <ST7 as Expression>::SqlType,
<ST8 as Expression>::SqlType, <ST9 as Expression>::SqlType,
<ST10 as Expression>::SqlType, <ST11 as Expression>::SqlType,
<ST12 as Expression>::SqlType, <ST13 as Expression>::SqlType,
<ST14 as Expression>::SqlType, <ST15 as Expression>::SqlType,
<ST16 as Expression>::SqlType, <ST17 as Expression>::SqlType,
<ST18 as Expression>::SqlType, <ST19 as Expression>::SqlType,
<ST20 as Expression>::SqlType, <ST21 as Expression>::SqlType,
<ST22 as Expression>::SqlType, <ST23 as Expression>::SqlType,
<ST24 as Expression>::SqlType, <ST25 as Expression>::SqlType,
<ST26 as Expression>::SqlType, <ST27 as Expression>::SqlType,
<ST28 as Expression>::SqlType, <ST29 as Expression>::SqlType,
<ST30 as Expression>::SqlType, <ST31 as Expression>::SqlType): SqlType,
T: Table + StaticQueryFragment, T::Component: QueryFragment<Pg>,
Self: ColumnList {
type Table = T;
type SqlType = crate::dsl::SqlTypeOf<Self>;
fn walk_target(mut pass: crate::query_builder::AstPass<'_, '_, Pg>)
-> crate::QueryResult<()> {
T::STATIC_COMPONENT.walk_ast(pass.reborrow())?;
pass.push_sql("(");
<Self as
ColumnList>::walk_ast(&(ST::default(), ST1::default(),
ST2::default(), ST3::default(), ST4::default(),
ST5::default(), ST6::default(), ST7::default(),
ST8::default(), ST9::default(), ST10::default(),
ST11::default(), ST12::default(), ST13::default(),
ST14::default(), ST15::default(), ST16::default(),
ST17::default(), ST18::default(), ST19::default(),
ST20::default(), ST21::default(), ST22::default(),
ST23::default(), ST24::default(), ST25::default(),
ST26::default(), ST27::default(), ST28::default(),
ST29::default(), ST30::default(), ST31::default()),
pass.reborrow())?;
pass.push_sql(")");
Ok(())
}
}diesel_derives::__diesel_for_each_tuple!(copy_target_for_columns);