use std::any::Any;
use arrow::datatypes::{DataType, SchemaRef};
use arrow::record_batch::RecordBatch;
use crate::errors::{ConnectorError, TableCreateError, TableDropError};
pub trait Connector {
type Stmt<'conn>: Statement<'conn>
where
Self: 'conn;
type Append<'conn>: Append<'conn>
where
Self: 'conn;
fn query<'a>(&'a mut self, query: &str) -> Result<Self::Stmt<'a>, ConnectorError>;
fn append<'a>(&'a mut self, table_name: &str) -> Result<Self::Append<'a>, ConnectorError>;
fn type_db_into_arrow(_database_ty: &str) -> Option<DataType>;
fn type_arrow_into_db(_ty: &DataType) -> Option<String>;
}
pub trait Statement<'conn> {
type Reader<'stmt>: ResultReader<'stmt>
where
Self: 'stmt;
fn start<'p, I>(&mut self, args: I) -> Result<Self::Reader<'_>, ConnectorError>
where
I: IntoIterator<Item = &'p dyn ArrowValue>,
{
let args: Vec<_> = args.into_iter().collect();
let batch = crate::params::vec_to_record_batch(args)?;
self.start_batch((&batch, 0))
}
fn start_batch(
&mut self,
args: (&RecordBatch, usize),
) -> Result<Self::Reader<'_>, ConnectorError>;
}
pub trait ResultReader<'stmt>: Iterator<Item = Result<RecordBatch, ConnectorError>> {
fn get_schema(&mut self) -> Result<SchemaRef, ConnectorError>;
}
pub const METADATA_DB_TYPE: &str = "db_type";
pub trait Append<'conn> {
fn append(&mut self, batch: RecordBatch) -> Result<(), ConnectorError>;
fn finish(self) -> Result<(), ConnectorError>;
}
pub trait SchemaGet {
fn table_list(&mut self) -> Result<Vec<String>, ConnectorError>;
fn table_get(&mut self, name: &str) -> Result<SchemaRef, ConnectorError>;
}
pub trait SchemaEdit {
fn table_create(&mut self, name: &str, schema: SchemaRef) -> Result<(), TableCreateError>;
fn table_drop(&mut self, name: &str) -> Result<(), TableDropError>;
}
pub trait ArrowValue: sealed::Sealed + Any + std::fmt::Debug {
fn get_data_type(&self) -> &DataType;
fn as_any(&self) -> &dyn Any;
}
pub(crate) mod sealed {
pub trait Sealed {}
}
pub mod unimplemented {
pub struct Appender;
impl super::Append<'_> for Appender {
fn append(
&mut self,
_: arrow::record_batch::RecordBatch,
) -> Result<(), crate::ConnectorError> {
unimplemented!()
}
fn finish(self) -> Result<(), crate::ConnectorError> {
unimplemented!()
}
}
}