From f7516ea22d14f9fad3aafc18982ba561dc465e42 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Wed, 17 Feb 2021 21:22:39 -0800 Subject: [PATCH] feat(core): add TypeInfo, Database::TypeInfo, Database::TypeId, and Column::type_info --- sqlx-core/src/column.rs | 12 ++++++++++-- sqlx-core/src/database.rs | 9 +++++---- sqlx-core/src/type_info.rs | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 6 deletions(-) create mode 100644 sqlx-core/src/type_info.rs diff --git a/sqlx-core/src/column.rs b/sqlx-core/src/column.rs index 5ab144ea..72ebb81e 100644 --- a/sqlx-core/src/column.rs +++ b/sqlx-core/src/column.rs @@ -1,7 +1,15 @@ +use crate::Database; + +/// Represents a column from a query. pub trait Column { - /// Returns the name or alias of the column. + type Database: Database; + + /// Returns the name of the column. fn name(&self) -> &str; - /// Returns the ordinal (also known as the index) of the column. + /// Returns the (zero-based) position of the column. fn ordinal(&self) -> usize; + + /// Returns type information of the column. + fn type_info(&self) -> &::TypeInfo; } diff --git a/sqlx-core/src/database.rs b/sqlx-core/src/database.rs index 4abdeed6..c9e44131 100644 --- a/sqlx-core/src/database.rs +++ b/sqlx-core/src/database.rs @@ -1,6 +1,7 @@ use std::fmt::Debug; +use std::hash::Hash; -use crate::{Column, QueryResult, Row}; +use crate::{Column, QueryResult, Row, TypeInfo}; /// A database driver. /// @@ -12,7 +13,7 @@ pub trait Database: 'static + Sized + Debug + for<'x> HasOutput<'x> + for<'r> HasRawValue<'r> { /// The concrete [`Column`] implementation for this database. - type Column: Column; + type Column: Column; /// The concrete [`Row`] implementation for this database. type Row: Row; @@ -21,10 +22,10 @@ pub trait Database: type QueryResult: QueryResult; /// The concrete [`TypeInfo`] implementation for this database. - type TypeInfo; + type TypeInfo: TypeInfo; /// The concrete [`TypeId`] implementation for this database. - type TypeId; + type TypeId: PartialEq + Hash + Clone + Copy; } /// Associates [`Database`] with an `Output` of a generic lifetime. diff --git a/sqlx-core/src/type_info.rs b/sqlx-core/src/type_info.rs new file mode 100644 index 00000000..594f13d7 --- /dev/null +++ b/sqlx-core/src/type_info.rs @@ -0,0 +1,38 @@ +use crate::Database; + +/// Provides information about a SQL type. +pub trait TypeInfo { + type Database: Database; + + /// Returns the unique identifier for this SQL type. + fn id(&self) -> ::TypeId; + + /// Returns `true` if the database could not determine the actual type. + /// + /// Most commonly this occurs in cases where `NULL` is directly used in + /// an expression. + /// + fn is_unknown(&self) -> bool { + false + } + + /// Returns `true` if this is a zero-sized type intended to never hold + /// a value, such as `void` in C. + /// + /// PostgreSQL can return this type for simple function expressions + /// where the function has no return type. + /// + fn is_void(&self) -> bool { + false + } + + /// Returns the name of this SQL type for this database. + /// + /// Length specifiers will not be included. Only the basename will + /// be returned. This should be a rough approximation of how they are + /// written in SQL in the given database. + /// + /// Common type names include `VARCHAR`, `INTEGER`, and `BIGINT`. + /// + fn name(&self) -> &str; +}