1use crate::error::{AuroraError, Result};
2use crate::network::protocol::{Request, Response};
3use crate::query::SimpleQueryBuilder;
4use crate::types::{Document, FieldType, Value};
5use std::collections::HashMap;
6use tokio::io::{AsyncReadExt, AsyncWriteExt};
7use tokio::net::TcpStream;
8
9pub struct Client {
10 stream: TcpStream,
11 current_transaction: Option<u64>,
12}
13
14impl Client {
15 pub async fn connect(addr: &str) -> Result<Self> {
17 let stream = TcpStream::connect(addr).await?;
18 Ok(Self {
19 stream,
20 current_transaction: None,
21 })
22 }
23
24 async fn send_request(&mut self, request: Request) -> Result<Response> {
26 let request_bytes = bincode::serialize(&request).map_err(AuroraError::Bincode)?;
27 let len_bytes = (request_bytes.len() as u32).to_le_bytes();
28
29 self.stream.write_all(&len_bytes).await?;
30 self.stream.write_all(&request_bytes).await?;
31
32 let mut len_bytes = [0u8; 4];
33 self.stream.read_exact(&mut len_bytes).await?;
34 let len = u32::from_le_bytes(len_bytes) as usize;
35
36 let mut buffer = vec![0u8; len];
37 self.stream.read_exact(&mut buffer).await?;
38
39 let response: Response = bincode::deserialize(&buffer).map_err(AuroraError::Bincode)?;
40
41 Ok(response)
42 }
43
44 pub async fn new_collection(
45 &mut self,
46 name: &str,
47 fields: Vec<(String, FieldType, bool)>,
48 ) -> Result<()> {
49 let req = Request::NewCollection {
50 name: name.to_string(),
51 fields,
52 };
53 match self.send_request(req).await? {
54 Response::Done => Ok(()),
55 Response::Error(e) => Err(AuroraError::Protocol(e)),
56 _ => Err(AuroraError::Protocol("Unexpected response".into())),
57 }
58 }
59
60 pub async fn insert(
61 &mut self,
62 collection: &str,
63 data: HashMap<String, Value>,
64 ) -> Result<String> {
65 let req = Request::Insert {
66 collection: collection.to_string(),
67 data,
68 };
69 match self.send_request(req).await? {
70 Response::Message(id) => Ok(id),
71 Response::Error(e) => Err(AuroraError::Protocol(e)),
72 _ => Err(AuroraError::Protocol("Unexpected response".into())),
73 }
74 }
75
76 pub async fn get_document(&mut self, collection: &str, id: &str) -> Result<Option<Document>> {
77 let req = Request::GetDocument {
78 collection: collection.to_string(),
79 id: id.to_string(),
80 };
81 match self.send_request(req).await? {
82 Response::Document(doc) => Ok(doc),
83 Response::Error(e) => Err(AuroraError::Protocol(e)),
84 _ => Err(AuroraError::Protocol("Unexpected response".into())),
85 }
86 }
87
88 pub async fn query(&mut self, builder: SimpleQueryBuilder) -> Result<Vec<Document>> {
89 let req = Request::Query(builder);
90 match self.send_request(req).await? {
91 Response::Documents(docs) => Ok(docs),
92 Response::Error(e) => Err(AuroraError::Protocol(e)),
93 _ => Err(AuroraError::Protocol("Unexpected response".into())),
94 }
95 }
96
97 pub async fn begin_transaction(&mut self) -> Result<u64> {
98 match self.send_request(Request::BeginTransaction).await? {
99 Response::TransactionId(tx_id) => {
100 self.current_transaction = Some(tx_id);
101 Ok(tx_id)
102 }
103 Response::Error(e) => Err(AuroraError::Protocol(e)),
104 _ => Err(AuroraError::Protocol("Unexpected response".into())),
105 }
106 }
107
108 pub async fn commit_transaction(&mut self) -> Result<()> {
109 let tx_id = self
110 .current_transaction
111 .ok_or_else(|| AuroraError::InvalidOperation("No active transaction".into()))?;
112
113 match self.send_request(Request::CommitTransaction(tx_id)).await? {
114 Response::Done => {
115 self.current_transaction = None;
116 Ok(())
117 }
118 Response::Error(e) => Err(AuroraError::Protocol(e)),
119 _ => Err(AuroraError::Protocol("Unexpected response".into())),
120 }
121 }
122
123 pub async fn rollback_transaction(&mut self) -> Result<()> {
124 let tx_id = self
125 .current_transaction
126 .ok_or_else(|| AuroraError::InvalidOperation("No active transaction".into()))?;
127
128 match self
129 .send_request(Request::RollbackTransaction(tx_id))
130 .await?
131 {
132 Response::Done => {
133 self.current_transaction = None;
134 Ok(())
135 }
136 Response::Error(e) => Err(AuroraError::Protocol(e)),
137 _ => Err(AuroraError::Protocol("Unexpected response".into())),
138 }
139 }
140
141 pub async fn delete(&mut self, key: &str) -> Result<()> {
142 match self.send_request(Request::Delete(key.to_string())).await? {
143 Response::Done => Ok(()),
144 Response::Error(e) => Err(AuroraError::Protocol(e)),
145 _ => Err(AuroraError::Protocol("Unexpected response".into())),
146 }
147 }
148}