From 1d52416f7042b1b6b157dc66f6daa96a96d342e2 Mon Sep 17 00:00:00 2001 From: Fabian-Lars Date: Sun, 5 Mar 2023 12:25:15 +0100 Subject: [PATCH] feat(sql): Improve type decoding. Adds support for time and dates (#266) * feat(sql): Improve type decoding. Adds support for time and dates * remove default feat * typo --- Cargo.lock | 4 +- plugins/sql/Cargo.toml | 5 +- plugins/sql/src/decode/mod.rs | 15 +++++ plugins/sql/src/decode/mysql.rs | 90 ++++++++++++++++++++++++++++++ plugins/sql/src/decode/postgres.rs | 82 +++++++++++++++++++++++++++ plugins/sql/src/decode/sqlite.rs | 74 ++++++++++++++++++++++++ plugins/sql/src/lib.rs | 11 +--- plugins/sql/src/plugin.rs | 57 +------------------ 8 files changed, 271 insertions(+), 67 deletions(-) create mode 100644 plugins/sql/src/decode/mod.rs create mode 100644 plugins/sql/src/decode/mysql.rs create mode 100644 plugins/sql/src/decode/postgres.rs create mode 100644 plugins/sql/src/decode/sqlite.rs diff --git a/Cargo.lock b/Cargo.lock index 35300066..d2a0e851 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3901,6 +3901,7 @@ dependencies = [ "sqlx-rt", "stringprep", "thiserror", + "time 0.3.17", "tokio-stream", "url", "webpki-roots", @@ -4380,13 +4381,14 @@ dependencies = [ name = "tauri-plugin-sql" version = "0.1.0" dependencies = [ - "futures", + "futures-core", "log", "serde", "serde_json", "sqlx", "tauri", "thiserror", + "time 0.3.17", "tokio", ] diff --git a/plugins/sql/Cargo.toml b/plugins/sql/Cargo.toml index c72e237c..502cd12c 100644 --- a/plugins/sql/Cargo.toml +++ b/plugins/sql/Cargo.toml @@ -15,9 +15,10 @@ serde_json.workspace = true tauri.workspace = true log.workspace = true thiserror.workspace = true -sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "json"] } +futures-core = "0.3" +sqlx = { version = "0.6", features = ["runtime-tokio-rustls", "json", "time"] } +time = "0.3" tokio = { version = "1", features = ["sync"] } -futures = "0.3" [features] sqlite = ["sqlx/sqlite"] diff --git a/plugins/sql/src/decode/mod.rs b/plugins/sql/src/decode/mod.rs new file mode 100644 index 00000000..415c99b8 --- /dev/null +++ b/plugins/sql/src/decode/mod.rs @@ -0,0 +1,15 @@ +#[cfg(feature = "mysql")] +mod mysql; +#[cfg(feature = "postgres")] +mod postgres; +#[cfg(feature = "sqlite")] +mod sqlite; + +#[cfg(feature = "mysql")] +pub(crate) use mysql::to_json; + +#[cfg(feature = "postgres")] +pub(crate) use postgres::to_json; + +#[cfg(feature = "sqlite")] +pub(crate) use sqlite::to_json; diff --git a/plugins/sql/src/decode/mysql.rs b/plugins/sql/src/decode/mysql.rs new file mode 100644 index 00000000..e68bd1ac --- /dev/null +++ b/plugins/sql/src/decode/mysql.rs @@ -0,0 +1,90 @@ +use serde_json::Value as JsonValue; +use sqlx::{mysql::MySqlValueRef, TypeInfo, Value, ValueRef}; +use time::{Date, OffsetDateTime, PrimitiveDateTime, Time}; + +use crate::Error; + +pub(crate) fn to_json(v: MySqlValueRef) -> Result { + if v.is_null() { + return Ok(JsonValue::Null); + } + + let res = match v.type_info().name() { + "CHAR" | "VARCHAR" | "TINYTEXT" | "TEXT" | "MEDIUMTEXT" | "LONGTEXT" | "ENUM" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode() { + JsonValue::String(v) + } else { + JsonValue::Null + } + } + "FLOAT" | "DOUBLE" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + JsonValue::from(v) + } else { + JsonValue::Null + } + } + "TINYINT" | "SMALLINT" | "INT" | "MEDIUMINT" | "BIGINT" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + JsonValue::Number(v.into()) + } else { + JsonValue::Null + } + } + "TINYINT UNSIGNED" | "SMALLINT UNSIGNED" | "INT UNSIGNED" | "MEDIUMINT UNSIGNED" + | "BIGINT UNSIGNED" | "YEAR" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + JsonValue::Number(v.into()) + } else { + JsonValue::Null + } + } + "BOOLEAN" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode() { + JsonValue::Bool(v) + } else { + JsonValue::Null + } + } + "DATE" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::() { + JsonValue::String(v.to_string()) + } else { + JsonValue::Null + } + } + "TIME" => { + if let Ok(v) = ValueRef::to_owned(&v).try_decode::