use std::borrow::{Borrow, Cow};
use std::collections::HashMap;
use std::time::Duration;
use url::Url;
use crate::error::RsdbcErrors;
pub mod error;
pub mod connection;
pub type Result<T> = std::result::Result<T, RsdbcErrors>;
#[derive(Debug, Clone)]
pub enum Value {
Int32(i32),
UInt32(u32),
String(String),
}
pub struct SQLWarning {
}
pub struct ConfigurationOption {
}
pub trait TransactionDefinition {
fn get_attribute(&self, attribute: &str) -> OptionValue;
}
pub struct TransactionOptions;
impl TransactionOptions {
const ISOLATION_LEVEL: &'static str = "isolation_level";
const READ_ONLY: &'static str = "read_only";
const NAME: &'static str = "name";
const LOCK_WAIT_TIMEOUT: &'static str = "lock_wait_timeout";
}
#[derive(Debug, Clone, PartialEq)]
#[non_exhaustive]
pub enum OptionValue {
Bool(bool),
Duration(Duration), Int(i32),
Map(HashMap<String, String>), String(String),
}
impl From<i32> for OptionValue {
fn from(value: i32) -> Self {
OptionValue::Int(value)
}
}
impl From<u16> for OptionValue {
fn from(value: u16) -> Self {
OptionValue::Int(value as i32)
}
}
impl From<bool> for OptionValue {
fn from(value: bool) -> Self {
OptionValue::Bool(value)
}
}
impl From<Cow<'_, str>> for OptionValue {
fn from(value: Cow<'_, str>) -> Self {
OptionValue::String(value.to_string())
}
}
impl From<String> for OptionValue {
fn from(value: String) -> Self {
OptionValue::String(value)
}
}
impl From<&str> for OptionValue {
fn from(value: &str) -> Self {
OptionValue::String(value.to_string())
}
}
impl From<Duration> for OptionValue {
fn from(value: Duration) -> Self {
OptionValue::Duration(value)
}
}
impl From<Url> for OptionValue {
fn from(value: Url) -> Self {
OptionValue::String(value.to_string())
}
}
impl From<HashMap<String, String>> for OptionValue {
fn from(value: HashMap<String, String>) -> Self {
OptionValue::Map(value)
}
}
impl From<HashMap<&str, &str>> for OptionValue {
fn from(value: HashMap<&str, &str>) -> Self {
let mut map = HashMap::new();
for (k, v) in value {
map.insert(k.to_string(), v.to_string());
}
OptionValue::Map(map)
}
}
fn parse_connection(url: &str) {
}
pub trait ResultSet {
fn meta_data(&self) -> Result<Box<dyn ResultSetMetaData>>;
fn next(&mut self) -> bool;
fn get_bool(&self, i: u64) -> Result<Option<bool>>;
fn get_i8(&self, i: u64) -> Result<Option<i8>>;
fn get_i16(&self, i: u64) -> Result<Option<i16>>;
fn get_i32(&self, i: u64) -> Result<Option<i32>>;
fn get_i64(&self, i: u64) -> Result<Option<i64>>;
fn get_f32(&self, i: u64) -> Result<Option<f32>>;
fn get_f64(&self, i: u64) -> Result<Option<f64>>;
fn get_string(&self, i: u64) -> Result<Option<String>>;
fn get_bytes(&self, i: u64) -> Result<Option<Vec<u8>>>;
}
pub trait ResultSetMetaData {
fn num_columns(&self) -> u64;
fn column_name(&self, i: u64) -> String;
fn column_type(&self, i: u64) -> DataType;
fn column_type_name(&self, i: u64) -> String;
fn precision(&self, i: u64) -> u64;
fn schema_name(&self, i: u64) -> String;
fn table_name(&self, i: u64) -> String;
fn is_nullable(&self, i: u64) -> String;
fn is_read_only(&self, i: u64) -> String;
}
pub trait Row<'stmt> {
fn get_via_index<R>(&self, index: u32) -> R;
fn get_via_name<R>(&self, name: &str) -> R;
}
pub trait RowMetadata {
fn get_column_metadata(index: i32) -> Result<Box<dyn ColumnMetadata>>;
fn get_column_metadata_by_name<S: Into<String>>(name: S) -> Result<Box<dyn ColumnMetadata>>;
fn get_column_metadatas() -> Vec<Box<dyn ColumnMetadata>>;
fn contains<S: Into<String>>(column_name: S) -> bool;
}
pub trait TypeInfo {
fn rust_type(&self) -> &'static str;
fn name(&self) -> &str;
}
pub enum RsdbcType {
Char,
Varchar,
Nchar,
Nvarchar,
Clob,
Nclob,
Boolean,
Varbinary,
Blob,
Integer,
Tinyint,
Smallint,
Bigint,
Numeric,
Decimal,
Float,
Real,
Double,
Date,
Time,
TimeWithTimeZone,
Timestamp,
TimestampWithTimeZone,
Collection,
}
impl TypeInfo for RsdbcType {
fn rust_type(&self) -> &'static str {
todo!()
}
fn name(&self) -> &str {
match self {
RsdbcType::Char => "CHAR",
RsdbcType::Varchar => "VARCHAR",
RsdbcType::Nchar => "NCHAR",
RsdbcType::Nvarchar => "NVARCHAR",
RsdbcType::Clob => "CLOB",
RsdbcType::Nclob => "NCLOB",
RsdbcType::Boolean => "BOOLEAN",
RsdbcType::Varbinary => "VARBINARY",
RsdbcType::Blob => "BLOB",
RsdbcType::Integer => "INTEGER",
RsdbcType::Tinyint => "TINYINT",
RsdbcType::Smallint => "SMALLINT",
RsdbcType::Bigint => "BIGINT",
RsdbcType::Numeric => "NUMERIC",
RsdbcType::Decimal => "DECIMAL",
RsdbcType::Float => "FLOAT",
RsdbcType::Real => "REAL",
RsdbcType::Double => "DOUBLE",
RsdbcType::Date => "DATE",
RsdbcType::Time => "TIME",
RsdbcType::TimeWithTimeZone => "TIME_WITH_TIME_ZONE",
RsdbcType::Timestamp => "TIMESTAMP",
RsdbcType::TimestampWithTimeZone => "TIMESTAMP_WITH_TIME_ZONE",
RsdbcType::Collection => "COLLECTION",
}
}
}
pub trait ColumnMetadata: ReadableMetadata {
}
pub enum Nullability {
Nullable,
NonNull,
Unknown
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum DataType {
Bool,
Byte,
Char,
Short,
Integer,
Float,
Double,
Decimal,
Date,
Time,
Datetime,
Utf8,
Binary,
}
#[derive(Debug, Clone)]
pub struct Column {
name: String,
data_type: DataType,
}
impl Column {
pub fn new(name: &str, data_type: DataType) -> Self {
Column {
name: name.to_owned(),
data_type,
}
}
}
impl ResultSetMetaData for Vec<Column> {
fn num_columns(&self) -> u64 {
self.len() as u64
}
fn column_name(&self, i: u64) -> String {
self[i as usize].name.clone()
}
fn column_type(&self, i: u64) -> DataType {
self[i as usize].data_type
}
fn column_type_name(&self, i: u64) -> String {
todo!()
}
fn precision(&self, i: u64) -> u64 {
todo!()
}
fn schema_name(&self, i: u64) -> String {
todo!()
}
fn table_name(&self, i: u64) -> String {
todo!()
}
fn is_nullable(&self, i: u64) -> String {
todo!()
}
fn is_read_only(&self, i: u64) -> String {
todo!()
}
}
pub trait DatabaseMetadata {
}
pub trait OutParameters: Readable {
fn get_metadata(&self) -> Box<dyn OutParametersMetadata>;
}
pub trait OutParametersMetadata {
fn get_parameter_metadata_by_index(&self, index: u32) -> Result<Box<dyn OutParameterMetadata>>;
fn get_parameter_metadata_by_name(&self, name: &str) -> Result<Box<dyn OutParameterMetadata>>;
fn get_parameter_metadatas(&self) -> Vec<Box<dyn OutParameterMetadata>>; }
pub trait OutParameterMetadata: ReadableMetadata {}
pub trait ReadableMetadata {
fn rust_type(&self) -> &'static str;
fn db_type(&self) -> dyn TypeInfo;
fn get_name(&self) -> String;
fn get_native_type_metadata(&self);
fn get_nullability(&self) -> Nullability {
Nullability::Unknown
}
fn get_precision(&self) -> Option<u64> {
None
}
fn get_scale(&self) -> Option<u64> {
None
}
}
pub trait Readable {
fn get<T: FromSql>(&self, index: u32) -> Result<T>;
fn get_by_name<S: Into<String>, T: FromSql>(&self, name: S) -> Result<T>;
}
pub type FomSqlResult<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
pub trait FromSql {
fn from_sql<T>(bytes: T) -> Result<Box<Self>>;
}
pub trait Parameter {
}
pub trait In {}
pub trait Out {}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
let result = 2 + 2;
assert_eq!(result, 4);
}
}