-
-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
issues-336 Third try impl postgres-array #467
Changes from 8 commits
ac92bd1
a2931d8
f554714
f32f6c8
8154a5a
010af8a
4cd974b
fa26dad
9335b75
21f115e
d5424aa
b882d86
7bba3e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,22 +17,33 @@ rust-version = "1.60" | |
[lib] | ||
|
||
[dependencies] | ||
sea-query = { version = "^0", path = ".." } | ||
sea-query = { version = "^0", path = "..", features = ["thread-safe"] } | ||
sqlx = { version = "^0.6.1", optional = true } | ||
serde_json = { version = "^1", optional = true } | ||
chrono = { version = "^0.4", default-features = false, features = ["clock"], optional = true } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we pub all these from a special I can imagine the two Cargo.toml might go out of sync in the future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We want to make our third-party libraries as part of public interface? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point |
||
postgres-types = { version = "^0", optional = true } | ||
rust_decimal = { version = "^1", optional = true } | ||
bigdecimal = { version = "^0.3", optional = true } | ||
uuid = { version = "^1", optional = true } | ||
proc-macro2 = { version = "1", optional = true } | ||
quote = { version = "^1", optional = true } | ||
time = { version = "^0.3", optional = true, features = ["macros", "formatting"] } | ||
ipnetwork = { version = "^0.19", optional = true } | ||
mac_address = { version = "^1.1", optional = true } | ||
|
||
[features] | ||
sqlx-mysql = ["sqlx/mysql"] | ||
sqlx-postgres = ["sqlx/postgres"] | ||
sqlx-sqlite = ["sqlx/sqlite"] | ||
sqlx-any = ["sqlx/any"] | ||
with-chrono = ["sqlx/chrono", "sea-query/with-chrono"] | ||
with-json = ["sqlx/json", "sea-query/with-json"] | ||
with-rust_decimal = ["sqlx/decimal", "sea-query/with-rust_decimal"] | ||
with-bigdecimal = ["sqlx/bigdecimal", "sea-query/with-bigdecimal"] | ||
with-uuid = ["sqlx/uuid", "sea-query/with-uuid"] | ||
with-time = ["sqlx/time", "sea-query/with-time"] | ||
with-ipnetwork = ["sqlx/ipnetwork", "sea-query/with-ipnetwork"] | ||
with-mac_address = ["sqlx/mac_address", "sea-query/with-mac_address"] | ||
with-chrono = ["sqlx/chrono", "sea-query/with-chrono", "chrono"] | ||
with-json = ["sqlx/json", "sea-query/with-json", "serde_json"] | ||
with-rust_decimal = ["sqlx/decimal", "sea-query/with-rust_decimal", "rust_decimal"] | ||
with-bigdecimal = ["sqlx/bigdecimal", "sea-query/with-bigdecimal", "bigdecimal"] | ||
with-uuid = ["sqlx/uuid", "sea-query/with-uuid", "uuid"] | ||
with-time = ["sqlx/time", "sea-query/with-time", "time"] | ||
with-ipnetwork = ["sqlx/ipnetwork", "sea-query/with-ipnetwork", "ipnetwork"] | ||
with-mac_address = ["sqlx/mac_address", "sea-query/with-mac_address", "mac_address"] | ||
postgres-array = ["sea-query/postgres-array"] | ||
runtime-async-std-native-tls = ["sqlx/runtime-async-std-native-tls"] | ||
runtime-async-std-rustls = ["sqlx/runtime-async-std-rustls", ] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,21 @@ | ||
#[cfg(feature = "with-bigdecimal")] | ||
use bigdecimal::BigDecimal; | ||
#[cfg(feature = "with-chrono")] | ||
use chrono::{DateTime, Local, NaiveDate, NaiveDateTime, NaiveTime, Utc}; | ||
#[cfg(feature = "with-ipnetwork")] | ||
use ipnetwork::IpNetwork; | ||
#[cfg(feature = "with-mac_address")] | ||
use mac_address::MacAddress; | ||
#[cfg(feature = "with-rust_decimal")] | ||
use rust_decimal::Decimal; | ||
#[cfg(feature = "with-json")] | ||
use serde_json::Value as Json; | ||
#[cfg(feature = "with-uuid")] | ||
use uuid::Uuid; | ||
|
||
use sea_query::{ArrayType, Value}; | ||
|
||
use crate::SqlxValues; | ||
use sea_query::Value; | ||
|
||
impl<'q> sqlx::IntoArguments<'q, sqlx::postgres::Postgres> for SqlxValues { | ||
fn into_arguments(self) -> sqlx::postgres::PgArguments { | ||
|
@@ -32,7 +48,7 @@ impl<'q> sqlx::IntoArguments<'q, sqlx::postgres::Postgres> for SqlxValues { | |
args.add(i.map(|i| i as i64)); | ||
} | ||
Value::BigUnsigned(i) => { | ||
args.add(i.map(|i| <i64 as std::convert::TryFrom<u64>>::try_from(i).unwrap())); | ||
args.add(i.map(|i| <i64 as TryFrom<u64>>::try_from(i).unwrap())); | ||
} | ||
Value::Float(f) => { | ||
args.add(f); | ||
|
@@ -105,10 +121,6 @@ impl<'q> sqlx::IntoArguments<'q, sqlx::postgres::Postgres> for SqlxValues { | |
Value::Json(j) => { | ||
args.add(j.as_deref()); | ||
} | ||
#[cfg(feature = "postgres-array")] | ||
Value::Array(_) => { | ||
panic!("SeaQuery doesn't support array arguments for Postgresql"); | ||
} | ||
#[cfg(feature = "with-ipnetwork")] | ||
Value::IpNetwork(ip) => { | ||
args.add(ip.as_deref()); | ||
|
@@ -117,6 +129,188 @@ impl<'q> sqlx::IntoArguments<'q, sqlx::postgres::Postgres> for SqlxValues { | |
Value::MacAddress(mac) => { | ||
args.add(mac.as_deref()); | ||
} | ||
#[cfg(feature = "postgres-array")] | ||
Value::Array(ty, v) => match ty { | ||
ArrayType::Bool => { | ||
let value: Option<Vec<bool>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think ordinary user won't see this message (unless someone intentionally construct a vector of boxed value with different value variants in it) but the error message itself can be more specific. Value::Array(ty, v).except("This Value::Array should consist of Value::Bool"); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
ArrayType::TinyInt => { | ||
let value: Option<Vec<i8>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
ArrayType::SmallInt => { | ||
let value: Option<Vec<i16>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
ArrayType::Int => { | ||
let value: Option<Vec<i32>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
ArrayType::BigInt => { | ||
let value: Option<Vec<i64>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
ArrayType::TinyUnsigned => { | ||
let value: Option<Vec<u8>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
let value: Option<Vec<i16>> = | ||
value.map(|vec| vec.into_iter().map(|i| i as i16).collect()); | ||
args.add(value) | ||
} | ||
ArrayType::SmallUnsigned => { | ||
let value: Option<Vec<u16>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
let value: Option<Vec<i32>> = | ||
value.map(|vec| vec.into_iter().map(|i| i as i32).collect()); | ||
args.add(value) | ||
} | ||
ArrayType::Unsigned => { | ||
let value: Option<Vec<u32>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
let value: Option<Vec<i64>> = | ||
value.map(|vec| vec.into_iter().map(|i| i as i64).collect()); | ||
args.add(value) | ||
} | ||
ArrayType::BigUnsigned => { | ||
let value: Option<Vec<u64>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
let value: Option<Vec<i64>> = value.map(|vec| { | ||
vec.into_iter() | ||
.map(|i| <i64 as TryFrom<u64>>::try_from(i).unwrap()) | ||
.collect() | ||
}); | ||
args.add(value) | ||
} | ||
ArrayType::Float => { | ||
let value: Option<Vec<f32>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
ArrayType::Double => { | ||
let value: Option<Vec<f64>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
ArrayType::String => { | ||
let value: Option<Vec<String>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
ArrayType::Char => { | ||
let value: Option<Vec<char>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
let value: Option<Vec<String>> = | ||
value.map(|vec| vec.into_iter().map(|c| c.to_string()).collect()); | ||
args.add(value) | ||
} | ||
ArrayType::Bytes => { | ||
let value: Option<Vec<Vec<u8>>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value) | ||
} | ||
#[cfg(feature = "with-chrono")] | ||
ArrayType::ChronoDate => { | ||
let value: Option<Vec<NaiveDate>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-chrono")] | ||
ArrayType::ChronoTime => { | ||
let value: Option<Vec<NaiveTime>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-chrono")] | ||
ArrayType::ChronoDateTime => { | ||
let value: Option<Vec<NaiveDateTime>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-chrono")] | ||
ArrayType::ChronoDateTimeUtc => { | ||
let value: Option<Vec<DateTime<Utc>>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-chrono")] | ||
ArrayType::ChronoDateTimeLocal => { | ||
let value: Option<Vec<DateTime<Local>>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-chrono")] | ||
ArrayType::ChronoDateTimeWithTimeZone => { | ||
let value: Option<Vec<DateTime<Local>>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-time")] | ||
ArrayType::TimeDate => { | ||
let value: Option<Vec<time::Date>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-time")] | ||
ArrayType::TimeTime => { | ||
let value: Option<Vec<time::Time>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-time")] | ||
ArrayType::TimeDateTime => { | ||
let value: Option<Vec<time::PrimitiveDateTime>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-time")] | ||
ArrayType::TimeDateTimeWithTimeZone => { | ||
let value: Option<Vec<time::OffsetDateTime>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-uuid")] | ||
ArrayType::Uuid => { | ||
let value: Option<Vec<Uuid>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-rust_decimal")] | ||
ArrayType::Decimal => { | ||
let value: Option<Vec<Decimal>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-bigdecimal")] | ||
ArrayType::BigDecimal => { | ||
let value: Option<Vec<BigDecimal>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-json")] | ||
ArrayType::Json => { | ||
let value: Option<Vec<Json>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-ipnetwork")] | ||
ArrayType::IpNetwork => { | ||
let value: Option<Vec<IpNetwork>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
#[cfg(feature = "with-mac_address")] | ||
ArrayType::MacAddress => { | ||
let value: Option<Vec<MacAddress>> = | ||
Value::Array(ty, v).except("Invalid type for array value"); | ||
args.add(value); | ||
} | ||
}, | ||
} | ||
} | ||
args | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense