use std::io::Cursor;
use std::sync::Arc;
use bytes::Buf;
use bytes::BytesMut;
use chrono_tz::Tz;
use tokio::io::AsyncReadExt;
use tokio::io::AsyncWriteExt;
use tokio::io::BufWriter;
use tokio::net::TcpStream;
use crate::binary::Encoder;
use crate::binary::Parser;
use crate::errors::Error;
use crate::errors::Result;
use crate::protocols::ExceptionResponse;
use crate::protocols::Packet;
use crate::protocols::SERVER_END_OF_STREAM;
use crate::types::Block;
use crate::types::Progress;
use crate::CHContext;
use crate::ClickHouseSession;
pub struct Connection {
pub buffer: BytesMut,
stream: BufWriter<TcpStream>,
pub session: Arc<dyn ClickHouseSession>,
tz: Tz,
with_stack_trace: bool,
compress: bool
}
impl Connection {
pub fn new(
stream: TcpStream,
session: Arc<dyn ClickHouseSession>,
timezone: String
) -> Result<Connection> {
let tz: Tz = timezone.parse()?;
Ok(Connection {
stream: BufWriter::new(stream),
buffer: BytesMut::with_capacity(4 * 1024),
session,
tz,
with_stack_trace: false,
compress: true
})
}
pub async fn read_packet(&mut self, ctx: &mut CHContext) -> crate::Result<Option<Packet>> {
loop {
if let Some(frame) = self.parse_packet(ctx)? {
return Ok(Some(frame));
}
if 0 == self.stream.read_buf(&mut self.buffer).await? {
if self.buffer.is_empty() {
return Ok(None);
} else {
return Err("connection reset by peer".into());
}
}
}
}
fn parse_packet(&mut self, ctx: &mut CHContext) -> crate::Result<Option<Packet>> {
let mut buf = Cursor::new(&self.buffer[..]);
let mut parser = Parser::new(&mut buf, self.tz);
let hello = ctx.hello.clone();
let packet = parser.parse_packet(&hello, self.compress);
match packet {
Ok(packet) => {
match &packet {
Packet::Query(ref query) => self.compress = query.compression > 0,
_ => {}
}
let len = buf.position() as usize;
buf.set_position(0);
self.buffer.advance(len);
Ok(Some(packet))
}
Err(err) if err.is_would_block() => Ok(None),
Err(e) => Err(e.into())
}
}
pub async fn write_block(&mut self, block: &Block) -> Result<()> {
let mut encoder = Encoder::new();
block.send_server_data(&mut encoder, self.compress);
self.stream.write_all(&encoder.get_buffer()).await?;
self.stream.flush().await?;
Ok(())
}
pub async fn write_progress(&mut self, progress: Progress, client_revision: u64) -> Result<()> {
let mut encoder = Encoder::new();
progress.write(&mut encoder, client_revision);
self.stream.write_all(&encoder.get_buffer()).await?;
self.stream.flush().await?;
Ok(())
}
pub async fn write_end_of_stream(&mut self) -> Result<()> {
let mut encoder = Encoder::new();
encoder.uvarint(SERVER_END_OF_STREAM);
self.write_bytes(encoder.get_buffer()).await?;
Ok(())
}
pub async fn write_error(&mut self, err: &Error) -> Result<()> {
let mut encoder = Encoder::new();
ExceptionResponse::write(&mut encoder, &err, self.with_stack_trace);
self.stream.write_all(&encoder.get_buffer()).await?;
self.stream.flush().await?;
Ok(())
}
pub async fn write_bytes(&mut self, bytes: Vec<u8>) -> Result<()> {
self.stream.write_all(&bytes).await?;
self.stream.flush().await?;
Ok(())
}
}