Ensure identifiers start with alphabetical character Rename parse_variable_name -> parse_column_name Add DB value parsers and condition parser placeholder Fix number parser, basic condition parser Move select parser to select module Add create statement parser Move condition parser to common; add delete statement parser Add drop statement parser Add insert parser Add update parser, combine operation parsers into one Add initial validation, fix compiler warnings Validation WIP Allow more spaces in create statement, update TableSchema struct Add create index parser and validator Add todo in parse_identifier Rework the new structure, many other changes
90 lines
2.9 KiB
Rust
90 lines
2.9 KiB
Rust
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 addr = "127.0.0.1:5432";
|
|
|
|
let mut stream = TcpStream::connect(addr).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?;
|
|
let mut line = String::new();
|
|
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);
|
|
line.clear();
|
|
let res = std::io::stdin().read_line(&mut line);
|
|
if let Ok(_) = res {
|
|
if line.eq("exit") {
|
|
break;
|
|
}
|
|
writer.write_proto(FrontendMessage::Query(QueryData {
|
|
query: line.clone().into(),
|
|
})).await?;
|
|
writer.flush().await?;
|
|
}
|
|
},
|
|
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!();
|
|
}
|