Skip to content

Commit

Permalink
feat: Text adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
abonander committed Nov 22, 2023
1 parent fda4159 commit 89681fb
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 7 deletions.
4 changes: 4 additions & 0 deletions sqlx-core/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ pub mod bstr;
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
mod json;

mod text;

#[cfg(feature = "uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid")))]
#[doc(no_inline)]
Expand Down Expand Up @@ -81,6 +83,8 @@ pub mod mac_address {
#[cfg(feature = "json")]
pub use json::{Json, JsonRawValue, JsonValue};

pub use text::Text;

/// Indicates that a SQL type is supported for a database.
///
/// ## Compile-time verification
Expand Down
123 changes: 123 additions & 0 deletions sqlx-core/src/types/text.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
use std::fmt::{Debug, Display};
use std::ops::{Deref, DerefMut};
use std::str::FromStr;

use crate::database::{Database, HasArguments, HasValueRef};
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::types::Type;

/// Map a SQL text value to/from a Rust type using [`Display`] and [`FromStr`].
///
/// This can be useful for types that do not have a direct SQL equivalent, or are simply not
/// supported by SQLx for one reason or another.
///
/// For strongly typed databases like Postgres, this will report the value's type as `TEXT`.
///
/// ### Example: `SocketAddr`
///
/// MySQL and SQLite do not have a native SQL equivalent for `SocketAddr`, so if you want to
/// store and retrieve instances of it, it makes sense to map it to `TEXT`:
///
/// ```rust,no_run
/// use uuid::Uuid;

Check failure on line 24 in sqlx-core/src/types/text.rs

View workflow job for this annotation

GitHub Actions / Unit Test (tokio, none)

unresolved import `uuid`
///
/// use time::OffsetDateTime;

Check failure on line 26 in sqlx-core/src/types/text.rs

View workflow job for this annotation

GitHub Actions / Unit Test (tokio, none)

unresolved import `time`
///
/// use std::net::SocketAddr;
///
/// use sqlx::Connection;
/// use sqlx::mysql::MySqlConnection;
/// use sqlx::types::Text;
///
/// #[derive(sqlx::FromRow, Debug)]
/// struct Login {
/// user_id: Uuid,
/// socket_addr: Text<SocketAddr>,
/// login_at: OffsetDateTime
/// }
///
/// # async fn main() -> Result<(), Box<dyn std::error::Error>> {

Check failure on line 41 in sqlx-core/src/types/text.rs

View workflow job for this annotation

GitHub Actions / Unit Test (tokio, none)

`main` function is not allowed to be `async`
///
/// let mut conn: MySqlConnection = MySqlConnection::connect("<DATABASE URL>").await?;
///
/// let user_id: Uuid = "e9a72cdc-d907-48d6-a488-c64a91fd063c".parse().unwrap();
/// let socket_addr: SocketAddr = "198.51.100.47:31790".parse().unwrap();
///
/// // CREATE TABLE user_login(user_id VARCHAR(36), socket_addr TEXT, login_at TIMESTAMP);
/// sqlx::query("INSERT INTO user_login(user_id, socket_addr, login_at) VALUES (?, ?, NOW())")
/// .bind(user_id)
/// .bind(Text(socket_addr))
/// .execute(&mut conn)
/// .await?;
///
/// let logins: Vec<Login> = sqlx::query_as("SELECT * FROM user_login")
/// .fetch_all(&mut conn)
/// .await?;
///
/// println!("Logins for user ID {user_id}: {logins:?}");
///
/// # Ok(())
/// # }
/// ```
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Text<T>(pub T);

impl<T> Text<T> {
/// Extract the inner value.
pub fn into_inner(self) -> T {
self.0
}
}

impl<T> Deref for Text<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<T> DerefMut for Text<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl<T, DB> Type<DB> for Text<T>
where
String: Type<DB>,
DB: Database,
{
fn type_info() -> DB::TypeInfo {
String::type_info()
}

fn compatible(ty: &DB::TypeInfo) -> bool {
String::compatible(ty)
}
}

impl<'q, T, DB> Encode<'q, DB> for Text<T>
where
T: Display,
String: Encode<'q, DB>,
DB: Database,
{
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
self.0.to_string().encode(buf)
}
}

impl<'r, T, DB> Decode<'r, DB> for Text<T>
where
T: FromStr,
BoxDynError: From<<T as FromStr>::Err>,
&'r str: Decode<'r, DB>,
DB: Database,
{
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
Ok(Text(<&'r str as Decode<'r, DB>>::decode(value)?.parse()?))
}
}
11 changes: 11 additions & 0 deletions sqlx-postgres/src/types/array.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use sqlx_core::bytes::Buf;
use sqlx_core::types::Text;
use std::borrow::Cow;

use crate::decode::Decode;
Expand Down Expand Up @@ -67,6 +68,16 @@ where
}
}

impl<T> PgHasArrayType for Text<T> {
fn array_type_info() -> PgTypeInfo {
String::array_type_info()
}

fn array_compatible(ty: &PgTypeInfo) -> bool {
String::array_compatible(ty)
}
}

impl<T> Type<Postgres> for [T]
where
T: PgHasArrayType,
Expand Down
6 changes: 4 additions & 2 deletions sqlx-sqlite/src/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,14 @@
//! over a floating-point type in the first place.
//!
//! Instead, you should only use a type affinity that SQLite will not attempt to convert implicitly,
//! such as `TEXT` or `BLOB`, and map values to/from SQLite as strings.
//! such as `TEXT` or `BLOB`, and map values to/from SQLite as strings. You can do this easily
//! using [the `Text` adapter].
//!
//!
//! [`decimal.c`]: https://www.sqlite.org/floatingpoint.html#the_decimal_c_extension
//! [amalgamation]: https://www.sqlite.org/amalgamation.html
//! [type-affinity]: https://www.sqlite.org/datatype3.html#type_affinity
//!
//! [the `Text` adapter]: Text
pub(crate) use sqlx_core::types::*;

Expand Down
60 changes: 56 additions & 4 deletions tests/mysql/types.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
extern crate time_ as time;

use std::net::SocketAddr;
#[cfg(feature = "rust_decimal")]
use std::str::FromStr;

use sqlx::mysql::MySql;
use sqlx::{Executor, Row};

use sqlx::types::Text;

use sqlx_test::{new, test_type};

test_type!(bool(MySql, "false" == false, "true" == true));
Expand Down Expand Up @@ -68,9 +72,10 @@ test_type!(uuid_simple<sqlx::types::uuid::fmt::Simple>(MySql,

#[cfg(feature = "chrono")]
mod chrono {
use super::*;
use sqlx::types::chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};

use super::*;

test_type!(chrono_date<NaiveDate>(MySql,
"DATE '2001-01-05'" == NaiveDate::from_ymd(2001, 1, 5),

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (5_7, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (5_7, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (5_7, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (5_7, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 80 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead
"DATE '2050-11-23'" == NaiveDate::from_ymd(2050, 11, 23)

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, async-std, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, async-std, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (8, tokio, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (verylatest, tokio, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (5_7, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (5_7, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (5_7, async-std, native-tls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MySQL (5_7, async-std, rustls)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead

Check warning on line 81 in tests/mysql/types.rs

View workflow job for this annotation

GitHub Actions / MariaDB (10_11, async-std, none)

use of deprecated associated function `sqlx::types::chrono::NaiveDate::from_ymd`: use `from_ymd_opt()` instead
Expand Down Expand Up @@ -137,10 +142,12 @@ mod chrono {

#[cfg(feature = "time")]
mod time_tests {
use super::*;
use sqlx::types::time::{Date, OffsetDateTime, PrimitiveDateTime, Time};
use time::macros::{date, time};

use sqlx::types::time::{Date, OffsetDateTime, PrimitiveDateTime, Time};

use super::*;

test_type!(time_date<Date>(
MySql,
"DATE '2001-01-05'" == date!(2001 - 1 - 5),
Expand Down Expand Up @@ -236,11 +243,13 @@ test_type!(decimal<sqlx::types::Decimal>(MySql,

#[cfg(feature = "json")]
mod json_tests {
use super::*;
use serde_json::{json, Value as JsonValue};

use sqlx::types::Json;
use sqlx_test::test_type;

use super::*;

test_type!(json<JsonValue>(
MySql,
// MySQL 8.0.27 changed `<=>` to return an unsigned integer
Expand Down Expand Up @@ -319,3 +328,46 @@ CREATE TEMPORARY TABLE with_bits (

Ok(())
}

#[sqlx_macros::test]
async fn test_text_adapter() -> anyhow::Result<()> {
#[derive(sqlx::FromRow, Debug, PartialEq, Eq)]
struct Login {
user_id: i32,
socket_addr: Text<SocketAddr>,
#[cfg(feature = "time")]
login_at: time::OffsetDateTime,
}

let mut conn = new::<MySql>().await?;

conn.execute(
r#"
CREATE TEMPORARY TABLE user_login (
user_id INT PRIMARY KEY AUTO_INCREMENT,
socket_addr TEXT NOT NULL,
login_at TIMESTAMP NOT NULL
);
"#,
)
.await?;

let user_id = 1234;
let socket_addr: SocketAddr = "198.51.100.47:31790".parse().unwrap();

sqlx::query("INSERT INTO user_login (user_id, socket_addr, login_at) VALUES (?, ?, NOW())")
.bind(user_id)
.bind(Text(socket_addr))
.execute(&mut conn)
.await?;

let last_login: Login =
sqlx::query_as("SELECT * FROM user_login ORDER BY login_at DESC LIMIT 1")
.fetch_one(&mut conn)
.await?;

assert_eq!(last_login.user_id, user_id);
assert_eq!(*last_login.socket_addr, socket_addr);

Ok(())
}
48 changes: 47 additions & 1 deletion tests/postgres/types.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
extern crate time_ as time;

use std::net::SocketAddr;
use std::ops::Bound;

use sqlx::postgres::types::{Oid, PgCiText, PgInterval, PgMoney, PgRange};
use sqlx::postgres::Postgres;
use sqlx_test::{test_decode_type, test_prepared_type, test_type};
use sqlx_test::{new, test_decode_type, test_prepared_type, test_type};

use sqlx_core::executor::Executor;
use sqlx_core::types::Text;
use std::str::FromStr;

test_type!(null<Option<i16>>(Postgres,
Expand Down Expand Up @@ -579,3 +582,46 @@ test_type!(ltree_vec<Vec<sqlx::postgres::types::PgLTree>>(Postgres,
sqlx::postgres::types::PgLTree::from_iter(["Alpha", "Beta", "Delta", "Gamma"]).unwrap()
]
));

#[sqlx_macros::test]
async fn test_text_adapter() -> anyhow::Result<()> {
#[derive(sqlx::FromRow, Debug, PartialEq, Eq)]
struct Login {
user_id: i32,
socket_addr: Text<SocketAddr>,
#[cfg(feature = "time")]
login_at: time::OffsetDateTime,
}

let mut conn = new::<Postgres>().await?;

conn.execute(
r#"
CREATE TEMPORARY TABLE user_login (
user_id INT PRIMARY KEY,
socket_addr TEXT NOT NULL,
login_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
"#,
)
.await?;

let user_id = 1234;
let socket_addr: SocketAddr = "198.51.100.47:31790".parse().unwrap();

sqlx::query("INSERT INTO user_login (user_id, socket_addr) VALUES ($1, $2)")
.bind(user_id)
.bind(Text(socket_addr))
.execute(&mut conn)
.await?;

let last_login: Login =
sqlx::query_as("SELECT * FROM user_login ORDER BY login_at DESC LIMIT 1")
.fetch_one(&mut conn)
.await?;

assert_eq!(last_login.user_id, user_id);
assert_eq!(*last_login.socket_addr, socket_addr);

Ok(())
}
Loading

0 comments on commit 89681fb

Please sign in to comment.