Merge branch 'joshtriplett-types'

This commit is contained in:
Ryan Leckey 2020-12-18 21:57:48 -08:00
commit 107d0ff870
No known key found for this signature in database
GPG Key ID: F8AA68C235AB08C9
8 changed files with 173 additions and 1 deletions

38
Cargo.lock generated
View File

@ -434,6 +434,9 @@ name = "cc"
version = "1.0.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1770ced377336a88a67c473594ccc14eca6f4559217c34f64aac8f83d641b40"
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
@ -1084,6 +1087,19 @@ dependencies = [
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "git2"
version = "0.13.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6f1a0238d7f8f8fd5ee642f4ebac4dbc03e03d1f78fbe7a3ede35dcf7e2224"
dependencies = [
"bitflags",
"libc",
"libgit2-sys",
"log",
"url",
]
[[package]]
name = "glob"
version = "0.3.0"
@ -1230,6 +1246,15 @@ version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]]
name = "jobserver"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2"
dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.45"
@ -1288,6 +1313,18 @@ version = "0.2.80"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d58d1b70b004888f764dfbf6a26a3b0342a1632d33968e4a179d8011c760614"
[[package]]
name = "libgit2-sys"
version = "0.12.14+1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f25af58e6495f7caf2919d08f212de550cfa3ed2f5e744988938ea292b9f549"
dependencies = [
"cc",
"libc",
"libz-sys",
"pkg-config",
]
[[package]]
name = "libm"
version = "0.2.1"
@ -2442,6 +2479,7 @@ dependencies = [
"bigdecimal",
"bit-vec",
"bitflags",
"bstr",
"byteorder",
"bytes",
"chrono",

View File

@ -52,7 +52,7 @@ offline = [ "sqlx-macros/offline", "sqlx-core/offline" ]
# intended mainly for CI and docs
all = [ "tls", "all-databases", "all-types" ]
all-databases = [ "mysql", "sqlite", "postgres", "mssql", "any" ]
all-types = [ "bigdecimal", "decimal", "json", "time", "chrono", "ipnetwork", "uuid", "bit-vec" ]
all-types = [ "bigdecimal", "decimal", "json", "time", "chrono", "ipnetwork", "uuid", "bit-vec", "bstr", "git2" ]
# previous runtimes, available as features for error messages better than just
# "feature doesn't exist"
@ -90,6 +90,8 @@ uuid = [ "sqlx-core/uuid", "sqlx-macros/uuid" ]
json = [ "sqlx-core/json", "sqlx-macros/json" ]
time = [ "sqlx-core/time", "sqlx-macros/time" ]
bit-vec = [ "sqlx-core/bit-vec", "sqlx-macros/bit-vec"]
bstr = [ "sqlx-core/bstr" ]
git2 = [ "sqlx-core/git2" ]
[dependencies]
sqlx-core = { version = "=0.4.0", path = "sqlx-core", default-features = false }

View File

@ -152,6 +152,10 @@ sqlx = { version = "0.4.0", features = [ "runtime-async-std-native-tls" ] }
- `time`: Add support for date and time types from `time` crate (alternative to `chrono`, prefered by `query!` macro, if both enabled)
- `bstr`: Add support for `bstr::BString`.
- `git2`: Add support for `git2::Oid`.
- `bigdecimal`: Add support for `NUMERIC` using the `bigdecimal` crate.
- `decimal`: Add support for `NUMERIC` using the `rust_decimal` crate.

View File

@ -106,4 +106,6 @@ webpki = { version = "0.21.3", optional = true }
webpki-roots = { version = "0.20.0", optional = true }
whoami = "1.0.1"
stringprep = "0.1.2"
bstr = { version = "0.2.14", default-features = false, features = [ "std" ], optional = true }
git2 = { version = "0.13.12", default-features = false, optional = true }
hashlink = "0.6.0"

View File

@ -0,0 +1,52 @@
/// Conversions between `bstr` types and SQL types.
use crate::database::{Database, HasArguments, HasValueRef};
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::types::Type;
pub use bstr::{BString, BStr, ByteSlice};
impl<DB> Type<DB> for BString
where
DB: Database,
[u8]: Type<DB>,
{
fn type_info() -> DB::TypeInfo {
<&[u8] as Type<DB>>::type_info()
}
fn compatible(ty: &DB::TypeInfo) -> bool {
<&[u8] as Type<DB>>::compatible(ty)
}
}
impl<'r, DB> Decode<'r, DB> for BString
where
DB: Database,
Vec<u8>: Decode<'r, DB>,
{
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
<Vec<u8> as Decode<DB>>::decode(value).map(BString::from)
}
}
impl<'q, DB: Database> Encode<'q, DB> for &'q BStr
where
DB: Database,
&'q [u8]: Encode<'q, DB>,
{
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
<&[u8] as Encode<DB>>::encode(self.as_bytes(), buf)
}
}
impl<'q, DB: Database> Encode<'q, DB> for BString
where
DB: Database,
Vec<u8>: Encode<'q, DB>,
{
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
<Vec<u8> as Encode<DB>>::encode(self.as_bytes().to_vec(), buf)
}
}

View File

@ -0,0 +1,42 @@
/// Conversions between `git2::Oid` and SQL types.
use crate::database::{Database, HasArguments, HasValueRef};
use crate::decode::Decode;
use crate::encode::{Encode, IsNull};
use crate::error::BoxDynError;
use crate::types::Type;
pub use git2::Oid;
impl<DB> Type<DB> for Oid
where
DB: Database,
[u8]: Type<DB>,
{
fn type_info() -> DB::TypeInfo {
<&[u8] as Type<DB>>::type_info()
}
fn compatible(ty: &DB::TypeInfo) -> bool {
<&[u8] as Type<DB>>::compatible(ty)
}
}
impl<'r, DB> Decode<'r, DB> for Oid
where
DB: Database,
&'r [u8]: Decode<'r, DB>,
{
fn decode(value: <DB as HasValueRef<'r>>::ValueRef) -> Result<Self, BoxDynError> {
<&[u8] as Decode<DB>>::decode(value).and_then(|bytes| Ok(Oid::from_bytes(bytes)?))
}
}
impl<'q, DB: Database> Encode<'q, DB> for Oid
where
DB: Database,
Vec<u8>: Encode<'q, DB>,
{
fn encode_by_ref(&self, buf: &mut <DB as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
<Vec<u8> as Encode<DB>>::encode(self.as_bytes().to_vec(), buf)
}
}

View File

@ -20,6 +20,14 @@
use crate::database::Database;
#[cfg(feature = "bstr")]
#[cfg_attr(docsrs, doc(cfg(feature = "bstr")))]
pub mod bstr;
#[cfg(feature = "git2")]
#[cfg_attr(docsrs, doc(cfg(feature = "git2")))]
pub mod git2;
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
mod json;

View File

@ -107,6 +107,30 @@ mod chrono {
));
}
#[cfg(feature = "bstr")]
mod bstr {
use super::*;
use sqlx::types::bstr::BString;
test_type!(bstring<BString>(Sqlite,
"cast('abc123' as blob)" == BString::from(&b"abc123"[..]),
"x'0001020304'" == BString::from(&b"\x00\x01\x02\x03\x04"[..])
));
}
#[cfg(feature = "git2")]
mod git2 {
use super::*;
use sqlx::types::git2::Oid;
test_type!(oid<Oid>(
Sqlite,
"x'0000000000000000000000000000000000000000'" == Oid::zero(),
"x'000102030405060708090a0b0c0d0e0f10111213'"
== Oid::from_str("000102030405060708090a0b0c0d0e0f10111213").unwrap()
));
}
#[cfg(feature = "uuid")]
test_type!(uuid<sqlx::types::Uuid>(Sqlite,
"x'b731678f636f4135bc6f19440c13bd19'"