Skip to content

Commit

Permalink
refactor: expose ColumnType to quaint::ResultSet (#4960)
Browse files Browse the repository at this point in the history
  • Loading branch information
Weakky authored Jul 22, 2024
1 parent a2d1c42 commit ff166c7
Show file tree
Hide file tree
Showing 42 changed files with 1,621 additions and 942 deletions.
29 changes: 17 additions & 12 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion quaint/.envrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export TEST_MYSQL="mysql://root:prisma@localhost:3306/prisma"
export TEST_MYSQL8="mysql://root:prisma@localhost:3307/prisma"
export TEST_MYSQL_MARIADB="mysql://root:prisma@localhost:3308/prisma"
export TEST_PSQL="postgres://postgres:prisma@localhost:5432/postgres"
export TEST_PSQL="postgresql://postgres:prisma@localhost:5432/postgres"
export TEST_CRDB="postgresql://[email protected]:26259/postgres"
export TEST_MSSQL="jdbc:sqlserver://localhost:1433;database=master;user=SA;password=<YourStrong@Passw0rd>;trustServerCertificate=true"
if command -v nix-shell &> /dev/null
Expand Down
7 changes: 4 additions & 3 deletions quaint/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ serde = { version = "1.0" }
sqlformat = { version = "0.2.3", optional = true }
uuid.workspace = true
crosstarget-utils = { path = "../libs/crosstarget-utils" }
concat-idents = "1.1.5"

[dev-dependencies]
once_cell = "1.3"
Expand Down Expand Up @@ -125,12 +126,12 @@ features = ["chrono", "column_decltype"]
optional = true

[target.'cfg(not(any(target_os = "macos", target_os = "ios")))'.dependencies.tiberius]
version = "0.11.6"
version = "0.11.8"
optional = true
features = ["sql-browser-tokio", "chrono", "bigdecimal"]

[target.'cfg(any(target_os = "macos", target_os = "ios"))'.dependencies.tiberius]
version = "0.11.2"
version = "0.11.8"
optional = true
default-features = false
features = [
Expand Down Expand Up @@ -183,4 +184,4 @@ features = ["compat"]
optional = true

[build-dependencies]
cfg_aliases = "0.1.0"
cfg_aliases = "0.2.1"
2 changes: 2 additions & 0 deletions quaint/src/connector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
//! implement the [Queryable](trait.Queryable.html) trait for generalized
//! querying interface.

mod column_type;
mod connection_info;

pub mod external;
Expand All @@ -24,6 +25,7 @@ mod transaction;
mod type_identifier;

pub use self::result_set::*;
pub use column_type::*;
pub use connection_info::*;

#[cfg(native)]
Expand Down
177 changes: 177 additions & 0 deletions quaint/src/connector/column_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
#[cfg(not(target_arch = "wasm32"))]
use super::TypeIdentifier;

use crate::{Value, ValueType};

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColumnType {
Int32,
Int64,
Float,
Double,
Text,
Bytes,
Boolean,
Char,
Numeric,
Json,
Xml,
Uuid,
DateTime,
Date,
Time,
Enum,

Int32Array,
Int64Array,
FloatArray,
DoubleArray,
TextArray,
CharArray,
BytesArray,
BooleanArray,
NumericArray,
JsonArray,
XmlArray,
UuidArray,
DateTimeArray,
DateArray,
TimeArray,

Unknown,
}

impl ColumnType {
pub fn is_unknown(&self) -> bool {
matches!(self, ColumnType::Unknown)
}
}

impl std::fmt::Display for ColumnType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ColumnType::Int32 => write!(f, "int"),
ColumnType::Int64 => write!(f, "bigint"),
ColumnType::Float => write!(f, "float"),
ColumnType::Double => write!(f, "double"),
ColumnType::Text => write!(f, "string"),
ColumnType::Enum => write!(f, "enum"),
ColumnType::Bytes => write!(f, "bytes"),
ColumnType::Boolean => write!(f, "bool"),
ColumnType::Char => write!(f, "char"),
ColumnType::Numeric => write!(f, "decimal"),
ColumnType::Json => write!(f, "json"),
ColumnType::Xml => write!(f, "xml"),
ColumnType::Uuid => write!(f, "uuid"),
ColumnType::DateTime => write!(f, "datetime"),
ColumnType::Date => write!(f, "date"),
ColumnType::Time => write!(f, "time"),
ColumnType::Int32Array => write!(f, "int-array"),
ColumnType::Int64Array => write!(f, "bigint-array"),
ColumnType::FloatArray => write!(f, "float-array"),
ColumnType::DoubleArray => write!(f, "double-array"),
ColumnType::TextArray => write!(f, "string-array"),
ColumnType::BytesArray => write!(f, "bytes-array"),
ColumnType::BooleanArray => write!(f, "bool-array"),
ColumnType::CharArray => write!(f, "char-array"),
ColumnType::NumericArray => write!(f, "decimal-array"),
ColumnType::JsonArray => write!(f, "json-array"),
ColumnType::XmlArray => write!(f, "xml-array"),
ColumnType::UuidArray => write!(f, "uuid-array"),
ColumnType::DateTimeArray => write!(f, "datetime-array"),
ColumnType::DateArray => write!(f, "date-array"),
ColumnType::TimeArray => write!(f, "time-array"),

ColumnType::Unknown => write!(f, "unknown"),
}
}
}

impl From<&Value<'_>> for ColumnType {
fn from(value: &Value<'_>) -> Self {
Self::from(&value.typed)
}
}

impl From<&ValueType<'_>> for ColumnType {
fn from(value: &ValueType) -> Self {
match value {
ValueType::Int32(_) => ColumnType::Int32,
ValueType::Int64(_) => ColumnType::Int64,
ValueType::Float(_) => ColumnType::Float,
ValueType::Double(_) => ColumnType::Double,
ValueType::Text(_) => ColumnType::Text,
ValueType::Enum(_, _) => ColumnType::Enum,
ValueType::EnumArray(_, _) => ColumnType::TextArray,
ValueType::Bytes(_) => ColumnType::Bytes,
ValueType::Boolean(_) => ColumnType::Boolean,
ValueType::Char(_) => ColumnType::Char,
ValueType::Numeric(_) => ColumnType::Numeric,
ValueType::Json(_) => ColumnType::Json,
ValueType::Xml(_) => ColumnType::Xml,
ValueType::Uuid(_) => ColumnType::Uuid,
ValueType::DateTime(_) => ColumnType::DateTime,
ValueType::Date(_) => ColumnType::Date,
ValueType::Time(_) => ColumnType::Time,
ValueType::Array(Some(vals)) if !vals.is_empty() => match &vals[0].typed {
ValueType::Int32(_) => ColumnType::Int32Array,
ValueType::Int64(_) => ColumnType::Int64Array,
ValueType::Float(_) => ColumnType::FloatArray,
ValueType::Double(_) => ColumnType::DoubleArray,
ValueType::Text(_) => ColumnType::TextArray,
ValueType::Enum(_, _) => ColumnType::TextArray,
ValueType::Bytes(_) => ColumnType::BytesArray,
ValueType::Boolean(_) => ColumnType::BooleanArray,
ValueType::Char(_) => ColumnType::CharArray,
ValueType::Numeric(_) => ColumnType::NumericArray,
ValueType::Json(_) => ColumnType::JsonArray,
ValueType::Xml(_) => ColumnType::TextArray,
ValueType::Uuid(_) => ColumnType::UuidArray,
ValueType::DateTime(_) => ColumnType::DateTimeArray,
ValueType::Date(_) => ColumnType::DateArray,
ValueType::Time(_) => ColumnType::TimeArray,
ValueType::Array(_) => ColumnType::Unknown,
ValueType::EnumArray(_, _) => ColumnType::Unknown,
},
ValueType::Array(_) => ColumnType::Unknown,
}
}
}

impl ColumnType {
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn from_type_identifier<T>(value: T) -> Self
where
T: TypeIdentifier,
{
if value.is_bool() {
ColumnType::Boolean
} else if value.is_bytes() {
ColumnType::Bytes
} else if value.is_date() {
ColumnType::Date
} else if value.is_datetime() {
ColumnType::DateTime
} else if value.is_time() {
ColumnType::Time
} else if value.is_double() {
ColumnType::Double
} else if value.is_float() {
ColumnType::Float
} else if value.is_int32() {
ColumnType::Int32
} else if value.is_int64() {
ColumnType::Int64
} else if value.is_enum() {
ColumnType::Enum
} else if value.is_json() {
ColumnType::Json
} else if value.is_real() {
ColumnType::Numeric
} else if value.is_text() {
ColumnType::Text
} else {
ColumnType::Unknown
}
}
}
43 changes: 43 additions & 0 deletions quaint/src/connector/mssql/native/column_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use crate::connector::ColumnType;
use tiberius::{Column, ColumnType as MssqlColumnType};

impl From<&Column> for ColumnType {
fn from(value: &Column) -> Self {
match value.column_type() {
MssqlColumnType::Null => ColumnType::Unknown,

MssqlColumnType::BigVarChar
| MssqlColumnType::BigChar
| MssqlColumnType::NVarchar
| MssqlColumnType::NChar
| MssqlColumnType::Text
| MssqlColumnType::NText => ColumnType::Text,

MssqlColumnType::Xml => ColumnType::Xml,

MssqlColumnType::Bit | MssqlColumnType::Bitn => ColumnType::Boolean,
MssqlColumnType::Int1 | MssqlColumnType::Int2 | MssqlColumnType::Int4 => ColumnType::Int32,
MssqlColumnType::Int8 | MssqlColumnType::Intn => ColumnType::Int64,

MssqlColumnType::Datetime2
| MssqlColumnType::Datetime4
| MssqlColumnType::Datetime
| MssqlColumnType::Datetimen
| MssqlColumnType::DatetimeOffsetn => ColumnType::DateTime,

MssqlColumnType::Float4 => ColumnType::Float,
MssqlColumnType::Float8 | MssqlColumnType::Money | MssqlColumnType::Money4 | MssqlColumnType::Floatn => {
ColumnType::Double
}
MssqlColumnType::Guid => ColumnType::Uuid,
MssqlColumnType::Decimaln | MssqlColumnType::Numericn => ColumnType::Numeric,
MssqlColumnType::Daten => ColumnType::Date,
MssqlColumnType::Timen => ColumnType::Time,
MssqlColumnType::BigVarBin | MssqlColumnType::BigBinary | MssqlColumnType::Image => ColumnType::Bytes,

MssqlColumnType::Udt | MssqlColumnType::SSVariant => {
unreachable!("UDT and SSVariant types are not supported by Tiberius.")
}
}
}
}
3 changes: 1 addition & 2 deletions quaint/src/connector/mssql/native/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use crate::ast::{Value, ValueType};
use bigdecimal::BigDecimal;
use std::{borrow::Cow, convert::TryFrom};

use tiberius::ToSql;
use tiberius::{ColumnData, FromSql, IntoSql};
use tiberius::{ColumnData, FromSql, IntoSql, ToSql};

impl<'a> IntoSql<'a> for &'a Value<'a> {
fn into_sql(self) -> ColumnData<'a> {
Expand Down
Loading

0 comments on commit ff166c7

Please sign in to comment.