58 个版本 (31 个重大更新)
0.32.4 | 2024年6月9日 |
---|---|
0.32.2 | 2024年4月1日 |
0.32.1 | 2024年3月18日 |
0.31.0 | 2023年10月16日 |
0.1.0 | 2017年7月25日 |
在 数据库接口 中排名 #186
每月下载量 170,803
在 204 个 Crates 中使用(直接使用 36 个)
1MB
24K SLoC
mysql_common
此crate是MySql基本协议原语的实现。
此crate
- 定义了基本MySql常量;
- 实现了对MySql
cached_sha2_password
,mysql_native_password
和旧版认证插件的必要功能; - 实现了MySql协议IO的辅助特质;
- 实现了支持预处理语句的命名参数;
- 实现了对MySql协议数据包子集的解析器(包括binlog数据包);
- 定义了MySql协议值和行的rust表示;
- 实现了MySql值和rust类型之间的转换,以及MySql行和rust类型元组之间的转换。
- 实现了 FromRow 和 FromValue derive宏
支持的rust类型
Crate提供了以下类型与MySql值的转换(请参阅MySql文档以了解数字类型的支持范围)。以下表格引用的是MySql协议类型(请参阅Value
结构),而不是MySql列类型。请参阅MySql文档以了解列和协议类型的对应关系
类型 | 说明 |
---|---|
{i,u}8..}128 ,{i,u}size |
MySql int/uint将被转换,字节将被解析。 ⚠️ 注意, {i,u}128 的范围大于MySql整数类型支持的,但仍然会进行序列化(作为十进制字节字符串)。 |
浮点32位 |
MySQL中的浮点数将转换为 f32 ,字节将被解析为 f32 。⚠️ MySQL中的双精度浮点数不会转换为 f32 以避免精度损失(参见 #17) |
浮点64位 |
MySQL中的浮点数和双精度浮点数将转换为 f64 ,字节将被解析为 f64 。 |
布尔型 |
MySQL中的整数 {0 ,1 } 或字节 {"0x30" ,"0x31" } |
向量<无符号8位整数> |
MySQL字节 |
字符串 |
MySQL字节解析为utf8 |
Duration (std 和 time ) |
MySQL时间或字节解析为MySQL时间字符串 |
time::PrimitiveDateTime (v0.2.x) |
MySQL日期时间或字节解析为MySQL日期时间字符串(⚠️ 有损!忽略微秒) |
time::Date (v0.2.x) |
MySQL日期或字节解析为MySQL日期字符串(⚠️ 有损!忽略微秒) |
time::Time (v0.2.x) |
MySQL时间或字节解析为MySQL时间字符串(⚠️ 有损!忽略微秒) |
time::Duration (v0.2.x) |
MySQL时间或字节解析为MySQL时间字符串 |
time::PrimitiveDateTime (v0.3.x) |
MySQL日期时间或字节解析为MySQL日期时间字符串(⚠️ 有损!忽略微秒) |
time::Date (v0.3.x) |
MySQL日期或字节解析为MySQL日期字符串(⚠️ 有损!忽略微秒) |
time::Time (v0.3.x) |
MySQL时间或字节解析为MySQL时间字符串(⚠️ 有损!忽略微秒) |
time::Duration (v0.3.x) |
MySQL时间或字节解析为MySQL时间字符串 |
chrono::NaiveTime |
MySQL日期或字节解析为MySQL日期字符串 |
chrono::NaiveDate |
MySQL日期或字节解析为MySQL日期字符串 |
chrono::NaiveDateTime |
MySQL日期或字节解析为MySQL日期字符串 |
uuid::Uuid |
使用 Uuid::from_slice 解析MySQL字节 |
serde_json::Value |
使用 serde_json::from_str 解析MySQL字节 |
mysql_common::反序列化<T:DeserializeOwned> |
使用 serde_json::from_str 解析MySQL字节 |
Option<T:FromValue> |
必须用于可空列以避免错误 |
decimal::Decimal |
使用 Decimal::from_str 解析MySQL中的整数、无符号整数或字节。⚠️ 注意,此类型不支持MySQL DECIMAL 类型的完整范围。 |
bigdecimal::BigDecimal (v0.2.x) |
使用 BigDecimal::parse_bytes 解析MySQL中的整数、无符号整数、浮点数或字节。⚠️ 注意,这种类型的范围大于MySQL支持的 DECIMAL 类型,但仍然会进行序列化。 |
bigdecimal::BigDecimal (v0.3.x) |
使用 BigDecimal::parse_bytes 解析MySQL中的整数、无符号整数、浮点数或字节。⚠️ 注意,这种类型的范围大于MySQL支持的 DECIMAL 类型,但仍然会进行序列化。 |
bigdecimal::BigDecimal (v0.4.x) |
使用 BigDecimal::parse_bytes 解析MySQL中的整数、无符号整数、浮点数或字节。⚠️ 注意,这种类型的范围大于MySQL支持的 DECIMAL 类型,但仍然会进行序列化。 |
num_bigint::{BigInt,BigUint} |
使用_::parse_bytes 解析MySQL的int,uint或bytes。⚠️ 注意,这种类型的范围大于MySQL整数类型所支持的,但仍然会进行序列化(作为十进制字节字符串)。 |
此外,该crate还为以下类型的列表提供了从行转换(参见FromRow
特质)
类型 | 说明 |
---|---|
Row |
Row 自身的简单转换。 |
T:FromValue |
对于单列的行。 |
(T1:FromValue[, ..., T12:FromValue]) |
将行转换为1-12元组的元组。 |
frunk::hlist::HList 类型 |
用于克服元组元数限制 |
Crate特性
特性 | 描述 | 默认 |
---|---|---|
bigdecimal02 |
启用bigdecimal v0.2.x类型支持 |
🔴 |
bigdecimal03 |
启用bigdecimal v0.3.x类型支持 |
🔴 |
bigdecimal |
启用bigdecimal v0.4.x类型支持 |
🟢 |
chrono |
启用chrono 类型支持 |
🔴 |
rust_decimal |
启用rust_decimal 类型支持 |
🟢 |
time02 |
启用time v0.2.x类型支持 |
🔴 |
time |
启用time v0.3.x类型支持 |
🟢 |
frunk |
启用FromRow 对frunk::Hlist! 类型的支持 |
🟢 |
derive |
启用FromValue 和FromRow 推导宏 |
🟢 |
binlog |
与binlog相关的功能 | 🟢 |
推导宏
FromValue
推导
支持的推导
- 对于枚举 – 应仔细阅读MySQL文档中相应的部分。
- 对于新类型(参见新类型习语) – 假定包装的类型本身满足
FromValue
。
枚举
容器属性
#[mysql(crate_name = "some_name")]
– 覆盖了猜测提供所需特质的crate的尝试#[mysql(rename_all = ...)]
– 根据给定的命名约定重命名所有变体。可能的值有 "lowercase", "UPPERCASE", "PascalCase", "camelCase", "snake_case", "SCREAMING_SNAKE_CASE", "kebab-case", "SCREAMING-KEBAB-CASE"#[mysql(is_integer)]
– 告诉 derive 宏该值是整数而不是 MySql 枚举。如果变体稀疏或大于 u16,宏不会警告,并且不会尝试解析文本表示形式。#[mysql(is_string)]
– 告诉 derive 宏该值是字符串而不是 MySql 枚举。如果变体稀疏或大于 u16,宏不会警告,并且不会尝试解析整数表示形式。
示例
给定在 MySql 端的 ENUM('x-small', 'small', 'medium', 'large', 'x-large')
fn main() {
/// Note: the `crate_name` attribute should not be necessary.
#[derive(FromValue)]
#[mysql(rename_all = "kebab-case", crate_name = "mysql_common")]
#[repr(u8)]
enum Size {
XSmall = 1,
Small,
Medium,
Large,
XLarge,
}
fn assert_from_row_works(x: Row) -> Size {
from_row(x)
}
}
Newtypes
预期包装值满足 FromValue
或提供了 deserialize_with
。注意,为了支持 FromRow
,包装值必须满足 Into<Value>
或必须提供 serialize_with
。
容器属性
#[mysql(crate_name = "some_name")]
– 覆盖了猜测导入类型所在包的尝试#[mysql(bound = "Foo: Bar, Baz: Quux")]
– 使用以下额外的界限#[mysql(deserialize_with = "some::path")]
– 使用以下函数来反序列化包装值。预期签名是fn (Value) -> Result<Wrapped, FromValueError>
。#[mysql(serialize_with = "some::path")]
– 使用以下函数来序列化包装的值。期望的签名是fn (Wrapped) -> Value
。
示例
/// Trivial example
#[derive(FromValue)]
struct Inch(i32);
/// Example of a {serialize|deserialize}_with.
#[derive(FromValue)]
#[mysql(deserialize_with = "neg_de", serialize_with = "neg_ser")]
struct Neg(i64);
/// Wrapped generic. Bounds are inferred.
#[derive(FromValue)]
struct Foo<T>(Option<T>);
/// Example of additional bounds.
#[derive(FromValue)]
#[mysql(bound = "'b: 'a, T: 'a, U: From<String>, V: From<u64>")]
struct Bar<'a, 'b, const N: usize, T, U, V>(ComplexTypeToWrap<'a, 'b, N, T, U, V>);
fn assert_from_row_works<'a, 'b, const N: usize, T, U, V>(x: Row) -> (Inch, Neg, Foo<u8>, Bar<'a, 'b, N, T, U, V>)
where 'b: 'a, T: 'a, U: From<String>, V: From<u64>,
{
from_row(x)
}
// test boilerplate..
/// Dummy complex type with additional bounds on FromValue impl.
struct ComplexTypeToWrap<'a, 'b, const N: usize, T, U, V>([(&'a T, &'b U, V); N]);
struct FakeIr;
impl TryFrom<Value> for FakeIr {
// ...
}
impl<'a, 'b: 'a, const N: usize, T: 'a, U: From<String>, V: From<u64>> From<FakeIr> for ComplexTypeToWrap<'a, 'b, N, T, U, V> {
// ...
}
impl From<FakeIr> for Value {
// ...
}
impl<'a, 'b: 'a, const N: usize, T: 'a, U: From<String>, V: From<u64>> FromValue for ComplexTypeToWrap<'a, 'b, N, T, U, V> {
type Intermediate = FakeIr;
}
fn neg_de(v: Value) -> Result<i64, FromValueError> {
match v {
Value::Int(x) => Ok(-x),
Value::UInt(x) => Ok(-(x as i64)),
x => Err(FromValueError(x)),
}
}
fn neg_ser(x: i64) -> Value {
Value::Int(-x)
}
FromRow
继承
也在结构体上定义了一些常量
const TABLE_NAME: &str
– 如果提供了table_name
const {}_FIELD: &str
– 对于每个结构体字段({}
是结构体字段名(不是列名)的 SCREAMING_SNAKE_CASE 表示形式)
支持的推导
- 对于具有命名字段的结构体 – 字段名将用作列名以查找值
容器属性
#[mysql(crate_name = "some_name")]
– 覆盖了猜测提供所需特质的crate的尝试#[mysql(rename_all = ...)]
– 根据给定的命名约定重命名所有列名。可能的值是 "lowercase","UPPERCASE","PascalCase","camelCase","snake_case","SCREAMING_SNAKE_CASE","kebab-case","SCREAMING-KEBAB-CASE"#[mysql(table_name = "some_name")]
– 在结构体上定义pub const TABLE_NAME: &str
字段属性
#[mysql(rename = "some_name")]
– 覆盖字段的列名#[mysql(json)]
- 列将被解释为包含字段类型值的 JSON 字符串
示例
/// Note: the `crate_name` attribute should not be necessary.
#[derive(Debug, PartialEq, Eq, FromRow)]
#[mysql(table_name = "Foos", crate_name = "mysql_common")]
struct Foo {
id: u64,
#[mysql(json, rename = "def")]
definition: Bar,
child: Option<u64>,
}
#[derive(Debug, serde::Deserialize, PartialEq, Eq)]
enum Bar {
Left,
Right,
}
/// Returns the following row:
///
/// ```
/// +----+-----------+-------+
/// | id | def | child |
/// +----+-----------+-------+
/// | 42 | '"Right"' | NULL |
/// +----+-----------+-------+
/// ```
fn get_row() -> Row {
// ...
}
assert_eq!(Foo::TABLE_NAME, "Foos");
assert_eq!(Foo::ID_FIELD, "id");
assert_eq!(Foo::DEFINITION_FIELD, "def");
assert_eq!(Foo::CHILD_FIELD, "child");
let foo = from_row::<Foo>(get_row());
assert_eq!(foo, Foo { id: 42, definition: Bar::Right, child: None });
许可证
根据以下之一获得许可
- Apache License,版本 2.0 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT),由您选择。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交用于包含在作品中的任何贡献,均应采用上述双重许可方式,不附加任何额外条款或条件。
依赖项
~11-23MB
~336K SLoC