use std::fmt::{self, Display, Formatter};
pub(crate) use sqlx_core::type_info::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
pub enum FirebirdSqlType {
Text,
Varying,
Short,
Long,
Float,
Double,
Timestamp,
Blob,
Date,
Time,
Int64,
Int128,
Boolean,
TimestampTz,
TimeTz,
DecFixed,
Dec64,
Dec128,
Null,
}
impl FirebirdSqlType {
pub fn name(&self) -> &'static str {
match self {
Self::Text => "CHAR",
Self::Varying => "VARCHAR",
Self::Short => "SMALLINT",
Self::Long => "INTEGER",
Self::Float => "FLOAT",
Self::Double => "DOUBLE PRECISION",
Self::Timestamp => "TIMESTAMP",
Self::Blob => "BLOB",
Self::Date => "DATE",
Self::Time => "TIME",
Self::Int64 => "BIGINT",
Self::Int128 => "INT128",
Self::Boolean => "BOOLEAN",
Self::TimestampTz => "TIMESTAMP WITH TIME ZONE",
Self::TimeTz => "TIME WITH TIME ZONE",
Self::DecFixed => "NUMERIC",
Self::Dec64 => "DECFLOAT(16)",
Self::Dec128 => "DECFLOAT(34)",
Self::Null => "NULL",
}
}
pub fn from_sqltype(sqltype: u32) -> Option<Self> {
match sqltype {
452 => Some(Self::Text),
448 => Some(Self::Varying),
500 => Some(Self::Short),
496 => Some(Self::Long),
482 => Some(Self::Float),
480 => Some(Self::Double),
510 => Some(Self::Timestamp),
520 => Some(Self::Blob),
570 => Some(Self::Date),
560 => Some(Self::Time),
580 => Some(Self::Int64),
32752 => Some(Self::Int128),
32764 => Some(Self::Boolean),
32754 => Some(Self::TimestampTz),
32756 => Some(Self::TimeTz),
32758 => Some(Self::DecFixed),
32760 => Some(Self::Dec64),
32762 => Some(Self::Dec128),
32766 => Some(Self::Null),
_ => None,
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "offline", derive(serde::Serialize, serde::Deserialize))]
pub struct FirebirdTypeInfo {
pub(crate) r#type: FirebirdSqlType,
pub(crate) sqlscale: i32,
pub(crate) sqlsubtype: i32,
}
impl FirebirdTypeInfo {
pub(crate) const fn new(r#type: FirebirdSqlType) -> Self {
Self {
r#type,
sqlscale: 0,
sqlsubtype: 0,
}
}
pub(crate) const fn with_scale(r#type: FirebirdSqlType, sqlscale: i32, sqlsubtype: i32) -> Self {
Self {
r#type,
sqlscale,
sqlsubtype,
}
}
#[doc(hidden)]
pub fn __type_feature_gate(&self) -> Option<&'static str> {
match self.r#type {
FirebirdSqlType::Date
| FirebirdSqlType::Time
| FirebirdSqlType::Timestamp
| FirebirdSqlType::TimestampTz
| FirebirdSqlType::TimeTz => Some("chrono"),
FirebirdSqlType::DecFixed
| FirebirdSqlType::Dec64
| FirebirdSqlType::Dec128 => Some("rust_decimal"),
_ => None,
}
}
}
impl Display for FirebirdTypeInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.pad(self.name())
}
}
impl TypeInfo for FirebirdTypeInfo {
fn is_null(&self) -> bool {
matches!(self.r#type, FirebirdSqlType::Null)
}
fn name(&self) -> &str {
self.r#type.name()
}
}
impl PartialEq<FirebirdTypeInfo> for FirebirdTypeInfo {
fn eq(&self, other: &FirebirdTypeInfo) -> bool {
if self.r#type != other.r#type {
return false;
}
match self.r#type {
FirebirdSqlType::Short
| FirebirdSqlType::Long
| FirebirdSqlType::Int64
| FirebirdSqlType::Int128 => {
self.sqlscale == other.sqlscale
}
FirebirdSqlType::Blob => {
self.sqlsubtype == other.sqlsubtype
}
_ => true,
}
}
}
impl Eq for FirebirdTypeInfo {}