Consolidate to FromSqlError::InvalidBlobSize (breaking)

This commit is contained in:
trevyn 2022-01-02 23:41:50 +03:00 committed by Thom Chiovoloni
parent 7f09d295ba
commit c759bc7527
7 changed files with 42 additions and 95 deletions

View File

@ -39,7 +39,7 @@ bundled-sqlcipher-vendored-openssl = ["libsqlite3-sys/bundled-sqlcipher-vendored
buildtime_bindgen = ["libsqlite3-sys/buildtime_bindgen"] buildtime_bindgen = ["libsqlite3-sys/buildtime_bindgen"]
limits = [] limits = []
hooks = [] hooks = []
i128_blob = ["byteorder"] i128_blob = []
sqlcipher = ["libsqlite3-sys/sqlcipher"] sqlcipher = ["libsqlite3-sys/sqlcipher"]
unlock_notify = ["libsqlite3-sys/unlock_notify"] unlock_notify = ["libsqlite3-sys/unlock_notify"]
# xSavepoint, xRelease and xRollbackTo: 3.7.7 (2011-06-23) # xSavepoint, xRelease and xRollbackTo: 3.7.7 (2011-06-23)
@ -105,7 +105,6 @@ serde_json = { version = "1.0", optional = true }
csv = { version = "1.1", optional = true } csv = { version = "1.1", optional = true }
url = { version = "2.1", optional = true } url = { version = "2.1", optional = true }
lazy_static = { version = "1.4", optional = true } lazy_static = { version = "1.4", optional = true }
byteorder = { version = "1.3", features = ["i128"], optional = true }
fallible-iterator = "0.2" fallible-iterator = "0.2"
fallible-streaming-iterator = "0.1" fallible-streaming-iterator = "0.1"
memchr = "2.3" memchr = "2.3"

View File

@ -202,12 +202,7 @@ impl From<FromSqlError> for Error {
// context. // context.
match err { match err {
FromSqlError::OutOfRange(val) => Error::IntegralValueOutOfRange(UNKNOWN_COLUMN, val), FromSqlError::OutOfRange(val) => Error::IntegralValueOutOfRange(UNKNOWN_COLUMN, val),
#[cfg(feature = "i128_blob")] FromSqlError::InvalidBlobSize { .. } => {
FromSqlError::InvalidI128Size(_) => {
Error::FromSqlConversionFailure(UNKNOWN_COLUMN, Type::Blob, Box::new(err))
}
#[cfg(feature = "uuid")]
FromSqlError::InvalidUuidSize(_) => {
Error::FromSqlConversionFailure(UNKNOWN_COLUMN, Type::Blob, Box::new(err)) Error::FromSqlConversionFailure(UNKNOWN_COLUMN, Type::Blob, Box::new(err))
} }
FromSqlError::Other(source) => { FromSqlError::Other(source) => {

View File

@ -144,15 +144,7 @@ impl Context<'_> {
FromSqlError::Other(err) => { FromSqlError::Other(err) => {
Error::FromSqlConversionFailure(idx, value.data_type(), err) Error::FromSqlConversionFailure(idx, value.data_type(), err)
} }
FromSqlError::InvalidSize(_, _) => { FromSqlError::InvalidBlobSize { .. } => {
Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
}
#[cfg(feature = "i128_blob")]
FromSqlError::InvalidI128Size(_) => {
Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
}
#[cfg(feature = "uuid")]
FromSqlError::InvalidUuidSize(_) => {
Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err)) Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
} }
}) })

View File

@ -288,23 +288,11 @@ impl<'stmt> Row<'stmt> {
), ),
FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i), FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
FromSqlError::Other(err) => { FromSqlError::Other(err) => {
Error::FromSqlConversionFailure(idx as usize, value.data_type(), err) Error::FromSqlConversionFailure(idx, value.data_type(), err)
} }
FromSqlError::InvalidSize(_, _) => { FromSqlError::InvalidBlobSize { .. } => {
Error::FromSqlConversionFailure(idx as usize, value.data_type(), Box::new(err)) Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
} }
#[cfg(feature = "i128_blob")]
FromSqlError::InvalidI128Size(_) => Error::InvalidColumnType(
idx,
self.stmt.column_name_unwrap(idx).into(),
value.data_type(),
),
#[cfg(feature = "uuid")]
FromSqlError::InvalidUuidSize(_) => Error::InvalidColumnType(
idx,
self.stmt.column_name_unwrap(idx).into(),
value.data_type(),
),
}) })
} }

View File

@ -16,21 +16,13 @@ pub enum FromSqlError {
OutOfRange(i64), OutOfRange(i64),
/// Error when the blob result returned by SQLite cannot be stored into the /// Error when the blob result returned by SQLite cannot be stored into the
/// requested type due to a size mismatch. (type size, blob size) /// requested type due to a size mismatch.
InvalidSize(usize, usize), InvalidBlobSize {
/// The expected size of the blob.
/// Error returned when reading an `i128` from a expected_size: usize,
/// blob with a size other than 16. Only available when the `i128_blob` /// The actual size of the blob that was returned.
/// feature is enabled. blob_size: usize,
#[cfg(feature = "i128_blob")] },
#[cfg_attr(docsrs, doc(cfg(feature = "i128_blob")))]
InvalidI128Size(usize),
/// Error returned when reading a `uuid` from a blob with
/// a size other than 16. Only available when the `uuid` feature is enabled.
#[cfg(feature = "uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid")))]
InvalidUuidSize(usize),
/// An error case available for implementors of the [`FromSql`] trait. /// An error case available for implementors of the [`FromSql`] trait.
Other(Box<dyn Error + Send + Sync + 'static>), Other(Box<dyn Error + Send + Sync + 'static>),
@ -41,10 +33,16 @@ impl PartialEq for FromSqlError {
match (self, other) { match (self, other) {
(FromSqlError::InvalidType, FromSqlError::InvalidType) => true, (FromSqlError::InvalidType, FromSqlError::InvalidType) => true,
(FromSqlError::OutOfRange(n1), FromSqlError::OutOfRange(n2)) => n1 == n2, (FromSqlError::OutOfRange(n1), FromSqlError::OutOfRange(n2)) => n1 == n2,
#[cfg(feature = "i128_blob")] (
(FromSqlError::InvalidI128Size(s1), FromSqlError::InvalidI128Size(s2)) => s1 == s2, FromSqlError::InvalidBlobSize {
#[cfg(feature = "uuid")] expected_size: es1,
(FromSqlError::InvalidUuidSize(s1), FromSqlError::InvalidUuidSize(s2)) => s1 == s2, blob_size: bs1,
},
FromSqlError::InvalidBlobSize {
expected_size: es2,
blob_size: bs2,
},
) => es1 == es2 && bs1 == bs2,
(..) => false, (..) => false,
} }
} }
@ -55,16 +53,15 @@ impl fmt::Display for FromSqlError {
match *self { match *self {
FromSqlError::InvalidType => write!(f, "Invalid type"), FromSqlError::InvalidType => write!(f, "Invalid type"),
FromSqlError::OutOfRange(i) => write!(f, "Value {} out of range", i), FromSqlError::OutOfRange(i) => write!(f, "Value {} out of range", i),
FromSqlError::InvalidSize(i, j) => { FromSqlError::InvalidBlobSize {
write!(f, "Cannot read {} byte value out of {} byte blob", i, j) expected_size,
} blob_size,
#[cfg(feature = "i128_blob")] } => {
FromSqlError::InvalidI128Size(s) => { write!(
write!(f, "Cannot read 128bit value out of {} byte blob", s) f,
} "Cannot read {} byte value out of {} byte blob",
#[cfg(feature = "uuid")] expected_size, blob_size
FromSqlError::InvalidUuidSize(s) => { )
write!(f, "Cannot read UUID value out of {} byte blob", s)
} }
FromSqlError::Other(ref err) => err.fmt(f), FromSqlError::Other(ref err) => err.fmt(f),
} }
@ -188,9 +185,10 @@ impl<const N: usize> FromSql for [u8; N] {
#[inline] #[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
let slice = value.as_blob()?; let slice = value.as_blob()?;
slice slice.try_into().map_err(|_| FromSqlError::InvalidBlobSize {
.try_into() expected_size: N,
.map_err(|_| FromSqlError::InvalidSize(N, slice.len())) blob_size: slice.len(),
})
} }
} }
@ -199,15 +197,8 @@ impl<const N: usize> FromSql for [u8; N] {
impl FromSql for i128 { impl FromSql for i128 {
#[inline] #[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
use byteorder::{BigEndian, ByteOrder}; let bytes = <[u8; 16]>::column_result(value)?;
Ok(i128::from_be_bytes(bytes) ^ (1i128 << 127))
value.as_blob().and_then(|bytes| {
if bytes.len() == 16 {
Ok(BigEndian::read_i128(bytes) ^ (1i128 << 127))
} else {
Err(FromSqlError::InvalidI128Size(bytes.len()))
}
})
} }
} }
@ -216,13 +207,8 @@ impl FromSql for i128 {
impl FromSql for uuid::Uuid { impl FromSql for uuid::Uuid {
#[inline] #[inline]
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> { fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
value let bytes = <[u8; 16]>::column_result(value)?;
.as_blob() Ok(uuid::Uuid::from_u128(u128::from_be_bytes(bytes)))
.and_then(|bytes| {
uuid::Builder::from_slice(bytes)
.map_err(|_| FromSqlError::InvalidUuidSize(bytes.len()))
})
.map(|mut builder| builder.build())
} }
} }

View File

@ -45,12 +45,9 @@ impl From<isize> for Value {
impl From<i128> for Value { impl From<i128> for Value {
#[inline] #[inline]
fn from(i: i128) -> Value { fn from(i: i128) -> Value {
use byteorder::{BigEndian, ByteOrder};
let mut buf = vec![0u8; 16];
// We store these biased (e.g. with the most significant bit flipped) // We store these biased (e.g. with the most significant bit flipped)
// so that comparisons with negative numbers work properly. // so that comparisons with negative numbers work properly.
BigEndian::write_i128(&mut buf, i ^ (1i128 << 127)); Value::Blob(i128::to_be_bytes(i ^ (1i128 << 127)).to_vec())
Value::Blob(buf)
} }
} }

View File

@ -600,20 +600,10 @@ impl Values<'_> {
FromSqlError::Other(err) => { FromSqlError::Other(err) => {
Error::FromSqlConversionFailure(idx, value.data_type(), err) Error::FromSqlConversionFailure(idx, value.data_type(), err)
} }
FromSqlError::InvalidSize(_, _) => { FromSqlError::InvalidBlobSize { .. } => {
Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err)) Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
} }
FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i), FromSqlError::OutOfRange(i) => Error::IntegralValueOutOfRange(idx, i),
#[cfg(feature = "i128_blob")]
#[cfg_attr(docsrs, doc(cfg(feature = "i128_blob")))]
FromSqlError::InvalidI128Size(_) => {
Error::InvalidColumnType(idx, idx.to_string(), value.data_type())
}
#[cfg(feature = "uuid")]
#[cfg_attr(docsrs, doc(cfg(feature = "uuid")))]
FromSqlError::InvalidUuidSize(_) => {
Error::FromSqlConversionFailure(idx, value.data_type(), Box::new(err))
}
}) })
} }