mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-02 15:25:32 +00:00
feat(mysql): support reading and writing BIT via unsigned integers
e.g., BIT(64) is u64 and BIT(2) is u8
This commit is contained in:
parent
7b132d1dbc
commit
ec0e84d8ac
@ -1,7 +1,5 @@
|
||||
use std::convert::TryInto;
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
use crate::decode::Decode;
|
||||
use crate::encode::{Encode, IsNull};
|
||||
use crate::error::BoxDynError;
|
||||
@ -14,6 +12,7 @@ fn uint_type_info(ty: ColumnType) -> MySqlTypeInfo {
|
||||
r#type: ty,
|
||||
flags: ColumnFlags::BINARY | ColumnFlags::UNSIGNED,
|
||||
char_set: 63,
|
||||
max_size: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +25,7 @@ fn uint_compatible(ty: &MySqlTypeInfo) -> bool {
|
||||
| ColumnType::Int24
|
||||
| ColumnType::LongLong
|
||||
| ColumnType::Year
|
||||
| ColumnType::Bit
|
||||
) && ty.flags.contains(ColumnFlags::UNSIGNED)
|
||||
}
|
||||
|
||||
@ -102,8 +102,22 @@ impl Encode<'_, MySql> for u64 {
|
||||
}
|
||||
|
||||
fn uint_decode(value: MySqlValueRef<'_>) -> Result<u64, BoxDynError> {
|
||||
if value.type_info.r#type == ColumnType::Bit {
|
||||
// NOTE: Regardless of the value format, there is raw binary data here
|
||||
|
||||
let buf = value.as_bytes()?;
|
||||
let mut value: u64 = 0;
|
||||
|
||||
for b in buf {
|
||||
value = (*b as u64) | (value << 8);
|
||||
}
|
||||
|
||||
return Ok(value);
|
||||
}
|
||||
|
||||
Ok(match value.format() {
|
||||
MySqlValueFormat::Text => value.as_str()?.parse()?,
|
||||
|
||||
MySqlValueFormat::Binary => {
|
||||
let buf = value.as_bytes()?;
|
||||
LittleEndian::read_uint(buf, buf.len())
|
||||
|
@ -12,10 +12,10 @@ type Error = Box<dyn std::error::Error>;
|
||||
|
||||
type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
mod common;
|
||||
mod database;
|
||||
mod derives;
|
||||
mod query;
|
||||
mod common;
|
||||
|
||||
#[cfg(feature = "migrate")]
|
||||
mod migrate;
|
||||
|
@ -5,7 +5,7 @@ use std::str::FromStr;
|
||||
|
||||
use sqlx::mysql::MySql;
|
||||
use sqlx::{Executor, Row};
|
||||
use sqlx_test::test_type;
|
||||
use sqlx_test::{test_type, new};
|
||||
|
||||
test_type!(bool(MySql, "false" == false, "true" == true));
|
||||
|
||||
@ -251,3 +251,38 @@ mod json_tests {
|
||||
"\'{\"json_column\":[1,2]}\'" == Json(Customer { json_column: Json(vec![1, 2]) })
|
||||
));
|
||||
}
|
||||
|
||||
#[sqlx_macros::test]
|
||||
async fn test_bits() -> anyhow::Result<()> {
|
||||
let mut conn = new::<MySql>().await?;
|
||||
|
||||
conn.execute(r#"
|
||||
CREATE TEMPORARY TABLE with_bits (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
value_1 BIT(1) NOT NULL,
|
||||
value_n BIT(64) NOT NULL
|
||||
);
|
||||
"#).await?;
|
||||
|
||||
sqlx::query("INSERT INTO with_bits (value_1, value_n) VALUES (?, ?)")
|
||||
.bind(&1_u8)
|
||||
.bind(&510202_u32)
|
||||
.execute(&mut conn)
|
||||
.await?;
|
||||
|
||||
// BINARY
|
||||
let (v1, vn): (u8, u64) = sqlx::query_as("SELECT value_1, value_n FROM with_bits").fetch_one(&mut conn).await?;
|
||||
|
||||
assert_eq!(v1, 1);
|
||||
assert_eq!(vn, 510202);
|
||||
|
||||
// TEXT
|
||||
let row = conn.fetch_one("SELECT value_1, value_n FROM with_bits").await?;
|
||||
let v1: u8 = row.try_get(0)?;
|
||||
let vn: u64 = row.try_get(1)?;
|
||||
|
||||
assert_eq!(v1, 1);
|
||||
assert_eq!(vn, 510202);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user