tank_postgres/
sql_writer.rs1use std::fmt::Write;
2use tank_core::{Context, SqlWriter, Value, future::Either, separated_by};
3
4pub struct PostgresSqlWriter {}
5
6impl SqlWriter for PostgresSqlWriter {
7 fn as_dyn(&self) -> &dyn SqlWriter {
8 self
9 }
10
11 fn write_column_type(&self, context: &mut Context, buff: &mut String, value: &Value) {
12 match value {
13 Value::Boolean(..) => buff.push_str("BOOLEAN"),
14 Value::Int8(..) => buff.push_str("SMALLINT"),
15 Value::Int16(..) => buff.push_str("SMALLINT"),
16 Value::Int32(..) => buff.push_str("INTEGER"),
17 Value::Int64(..) => buff.push_str("BIGINT"),
18 Value::Int128(..) => buff.push_str("NUMERIC(38)"),
19 Value::UInt8(..) => buff.push_str("SMALLINT"),
20 Value::UInt16(..) => buff.push_str("INTEGER"),
21 Value::UInt32(..) => buff.push_str("BIGINT"),
22 Value::UInt64(..) => buff.push_str("NUMERIC(19)"),
23 Value::UInt128(..) => buff.push_str("NUMERIC(38)"),
24 Value::Float32(..) => buff.push_str("FLOAT4"),
25 Value::Float64(..) => buff.push_str("FLOAT8"),
26 Value::Decimal(.., precision, scale) => {
27 buff.push_str("NUMERIC");
28 if (precision, scale) != (&0, &0) {
29 let _ = write!(buff, "({},{})", precision, scale);
30 }
31 }
32 Value::Char(..) => buff.push_str("CHARACTER(1)"),
33 Value::Varchar(..) => buff.push_str("TEXT"),
34 Value::Blob(..) => buff.push_str("BYTEA"),
35 Value::Date(..) => buff.push_str("DATE"),
36 Value::Time(..) => buff.push_str("TIME"),
37 Value::Timestamp(..) => buff.push_str("TIMESTAMP"),
38 Value::TimestampWithTimezone(..) => buff.push_str("TIMESTAMP WITH TIME ZONE"),
39 Value::Interval(..) => buff.push_str("INTERVAL"),
40 Value::Uuid(..) => buff.push_str("UUID"),
41 Value::Array(.., inner, size) => {
42 self.write_column_type(context, buff, inner);
43 let _ = write!(buff, "[{}]", size);
44 }
45 Value::List(.., inner) => {
46 self.write_column_type(context, buff, inner);
47 buff.push_str("[]");
48 }
49 _ => log::error!(
50 "Unexpected tank::Value, variant {:?} is not supported",
51 value
52 ),
53 };
54 }
55
56 fn write_value_blob(&self, _context: &mut Context, buff: &mut String, value: &[u8]) {
57 buff.push_str("'\\x");
58 for b in value {
59 let _ = write!(buff, "{:X}", b);
60 }
61 buff.push('\'');
62 }
63
64 fn write_value_list<'a>(
65 &self,
66 context: &mut Context,
67 buff: &mut String,
68 value: Either<&Box<[Value]>, &Vec<Value>>,
69 ty: &Value,
70 ) {
71 buff.push_str("ARRAY[");
72 separated_by(
73 buff,
74 match value {
75 Either::Left(v) => v.iter(),
76 Either::Right(v) => v.iter(),
77 },
78 |buff, v| {
79 self.write_value(context, buff, v);
80 },
81 ",",
82 );
83 buff.push_str("]::");
84 self.write_column_type(context, buff, ty);
85 }
86
87 fn write_expression_operand_question_mark(&self, context: &mut Context, buff: &mut String) {
88 context.counter += 1;
89 let _ = write!(buff, "${}", context.counter);
90 }
91}