use std::collections::HashSet;
use arrow_array::{RecordBatch, RecordBatchReader};
use arrow_schema::Schema;
use crate::error::Result;
use crate::options::{self, OptionConnection, OptionDatabase, OptionStatement, OptionValue};
use crate::PartitionedResult;
pub trait Optionable {
type Option: AsRef<str>;
fn set_option(&mut self, key: Self::Option, value: OptionValue) -> Result<()>;
fn get_option_string(&self, key: Self::Option) -> Result<String>;
fn get_option_bytes(&self, key: Self::Option) -> Result<Vec<u8>>;
fn get_option_int(&self, key: Self::Option) -> Result<i64>;
fn get_option_double(&self, key: Self::Option) -> Result<f64>;
}
pub trait Driver {
type DatabaseType: Database;
fn new_database(&mut self) -> Result<Self::DatabaseType>;
fn new_database_with_opts(
&mut self,
opts: impl IntoIterator<Item = (OptionDatabase, OptionValue)>,
) -> Result<Self::DatabaseType>;
}
pub trait Database: Optionable<Option = OptionDatabase> {
type ConnectionType: Connection;
fn new_connection(&self) -> Result<Self::ConnectionType>;
fn new_connection_with_opts(
&self,
opts: impl IntoIterator<Item = (options::OptionConnection, OptionValue)>,
) -> Result<Self::ConnectionType>;
}
pub trait Connection: Optionable<Option = OptionConnection> {
type StatementType: Statement;
fn new_statement(&mut self) -> Result<Self::StatementType>;
fn cancel(&mut self) -> Result<()>;
fn get_info(
&self,
codes: Option<HashSet<options::InfoCode>>,
) -> Result<Box<dyn RecordBatchReader + Send + 'static>>;
fn get_objects(
&self,
depth: options::ObjectDepth,
catalog: Option<&str>,
db_schema: Option<&str>,
table_name: Option<&str>,
table_type: Option<Vec<&str>>,
column_name: Option<&str>,
) -> Result<Box<dyn RecordBatchReader + Send + 'static>>;
fn get_table_schema(
&self,
catalog: Option<&str>,
db_schema: Option<&str>,
table_name: &str,
) -> Result<Schema>;
fn get_table_types(&self) -> Result<Box<dyn RecordBatchReader + Send + 'static>>;
fn get_statistic_names(&self) -> Result<Box<dyn RecordBatchReader + Send + 'static>>;
fn get_statistics(
&self,
catalog: Option<&str>,
db_schema: Option<&str>,
table_name: Option<&str>,
approximate: bool,
) -> Result<Box<dyn RecordBatchReader + Send + 'static>>;
fn commit(&mut self) -> Result<()>;
fn rollback(&mut self) -> Result<()>;
fn read_partition(
&self,
partition: impl AsRef<[u8]>,
) -> Result<Box<dyn RecordBatchReader + Send + 'static>>;
}
pub trait Statement: Optionable<Option = OptionStatement> {
fn bind(&mut self, batch: RecordBatch) -> Result<()>;
fn bind_stream(&mut self, reader: Box<dyn RecordBatchReader + Send>) -> Result<()>;
fn execute(&mut self) -> Result<Box<dyn RecordBatchReader + Send + 'static>>;
fn execute_update(&mut self) -> Result<Option<i64>>;
fn execute_schema(&mut self) -> Result<Schema>;
fn execute_partitions(&mut self) -> Result<PartitionedResult>;
fn get_parameter_schema(&self) -> Result<Schema>;
fn prepare(&mut self) -> Result<()>;
fn set_sql_query(&mut self, query: impl AsRef<str>) -> Result<()>;
fn set_substrait_plan(&mut self, plan: impl AsRef<[u8]>) -> Result<()>;
fn cancel(&mut self) -> Result<()>;
}