feat(proto): add example client

This commit is contained in:
Jindřich Moravec 2023-12-23 23:40:31 +01:00
parent 75b067762e
commit 0318169876
4 changed files with 118 additions and 0 deletions

11
client/Cargo.toml Normal file
View file

@ -0,0 +1,11 @@
[package]
name = "client"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio = { version = "1.35.1", features = ["full"] }
anyhow = "1.0.76"
proto = { path = "../proto" }

80
client/src/main.rs Normal file
View file

@ -0,0 +1,80 @@
use proto::handshake::client::do_client_handshake;
use proto::handshake::request::HandshakeRequest;
use proto::reader::protoreader::ProtoReader;
use proto::writer::protowriter::{ProtoFlush, ProtoWriter};
use tokio::io::{BufReader, BufWriter};
use tokio::net::TcpStream;
use proto::message::backend::{BackendMessage, DataRowData, RowDescriptionData};
use proto::message::frontend::{FrontendMessage, QueryData};
use proto::reader::oneway::OneWayProtoReader;
use proto::writer::oneway::OneWayProtoWriter;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let add = "127.0.0.1:5432";
let mut stream = TcpStream::connect(add).await?;
let (reader, writer) = stream.split();
let mut writer = ProtoWriter::new(BufWriter::new(writer));
let mut reader = ProtoReader::new(BufReader::new(reader), 1024);
let request = HandshakeRequest::new(196608)
.parameter("user", "test user")
.parameter("client_encoding", "UTF8");
let response = do_client_handshake(&mut writer, &mut reader, request).await?;
println!("Handshake complete:\n{response:?}");
writer.write_proto(FrontendMessage::Query(QueryData {
query: "SELECT * FROM users;".to_string().into(),
})).await?;
writer.flush().await?;
loop {
let msg: BackendMessage = reader.read_proto().await?;
match msg {
BackendMessage::RowDescription(data) => {
print_header(data);
},
BackendMessage::DataRow(data) => {
print_row(data);
},
BackendMessage::CommandComplete(data) => {
println!("Command complete: {:?}", data);
},
BackendMessage::ReadyForQuery(data) => {
println!("Ready for query: {:?}", data);
break;
},
m => {
println!("Unexpected message: {:?}", m);
}
}
}
writer.write_proto(FrontendMessage::Terminate).await?;
writer.flush().await?;
Ok(())
}
fn print_header(header: RowDescriptionData) {
print!("Header -> ");
for column in Vec::from(header.columns) {
print!("{} | ", column.name.as_str());
}
println!();
}
fn print_row(row: DataRowData) {
print!("Row -> ");
for column in Vec::from(row.columns) {
let bytes = Vec::from(column);
let string = String::from_utf8(bytes).unwrap();
print!("{} | ", string);
}
println!();
}