40个版本

0.11.0 2023年12月17日
0.10.0 2023年1月7日
0.9.6 2021年8月28日
0.9.5 2021年6月6日
0.5.2 2017年12月27日

#473 in 数据库接口

每月 25 次下载
piedb 中使用

MIT/Apache

325KB
5.5K SLoC

msql-srv-rs

Crates.io Documentation Codecov Dependency status Maintenance

模拟MySQL/MariaDB服务器的绑定。

在开发新的数据库或缓存层时,使用现有应用程序测试您的系统非常有用。然而,这通常需要修改应用程序以使用您的数据库,而不是现有的数据库。这个crate通过充当MySQL服务器,并将查询和查询执行等操作委托给用户定义的逻辑来解决此问题。

首先,为您的后端实现 MysqlShim,并在您的后端实例和连接流上创建一个 MysqlIntermediary。当客户端发出 QUERYPREPAREEXECUTE 命令时,将在您的后端调用适当的方法,您将有机会做出适当的响应。例如,要编写一个始终以“无结果”回复响应所有命令的shim

extern crate mysql;
use msql_srv::*;
use mysql::prelude::*;

struct Backend;
impl<W: io::Write> MysqlShim<W> for Backend {
    type Error = io::Error;

    fn on_prepare(&mut self, _: &str, info: StatementMetaWriter<W>) -> io::Result<()> {
        info.reply(42, &[], &[])
    }
    fn on_execute(
        &mut self,
        _: u32,
        _: ParamParser,
        results: QueryResultWriter<W>,
    ) -> io::Result<()> {
        results.completed(0, 0)
    }
    fn on_close(&mut self, _: u32) {}

    fn on_init(&mut self, _: &str, writer: InitWriter<W>) -> io::Result<()> { Ok(()) }

    fn on_query(&mut self, _: &str, results: QueryResultWriter<W>) -> io::Result<()> {
        let cols = [
            Column {
                table: "foo".to_string(),
                column: "a".to_string(),
                coltype: ColumnType::MYSQL_TYPE_LONGLONG,
                colflags: ColumnFlags::empty(),
            },
            Column {
                table: "foo".to_string(),
                column: "b".to_string(),
                coltype: ColumnType::MYSQL_TYPE_STRING,
                colflags: ColumnFlags::empty(),
            },
        ];

        let mut rw = results.start(&cols)?;
        rw.write_col(42)?;
        rw.write_col("b's value")?;
        rw.finish()
    }
}

fn main() {
    let listener = net::TcpListener::bind("127.0.0.1:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    let jh = thread::spawn(move || {
        if let Ok((s, _)) = listener.accept() {
            MysqlIntermediary::run_on_tcp(Backend, s).unwrap();
        }
    });

    let mut db = mysql::Conn::new(&format!("mysql://127.0.0.1:{}", port)).unwrap();
    assert_eq!(db.ping(), true);
    assert_eq!(db.query_iter("SELECT a, b FROM foo").unwrap().count(), 1);
    drop(db);
    jh.join().unwrap();
}

依赖项

~13–26MB
~407K SLoC