代码之家  ›  专栏  ›  技术社区  ›  Sartor

如何将所有行作为提比略期货的向量?

  •  2
  • Sartor  · 技术社区  · 7 年前

    我需要使用 tiberius 并将其输出。我的简单代码是:

    extern crate futures;
    extern crate tokio_core;
    extern crate tiberius;
    
    use futures::Future;
    use tokio_core::reactor::Core;
    use tiberius::SqlConnection;
    use tiberius::stmt::ResultStreamExt;
    
    fn main() {
        let mut core = Core::new().unwrap();
    
        let future = SqlConnection::connect(core.handle(), "server=tcp:127.0.0.1,1433;username=SA;password=qweasdZXC123!!;")
            .and_then(|conn| {
                let mut v: Vec<String> = Vec::new();
    
                conn.simple_query("SELECT id, name FROM test").for_each_row(|row| {
    
                    let id: i32 = row.get(0);
                    let name: &str = row.get(1);
    
                    v.push(format!("{} - {}", id, name));
    
                    Ok(())
                });
    
                println!("{:?}", v);
    
                Ok(())
            });
    
        core.run(future).unwrap();
    }
    

    1 回复  |  直到 7 年前
        1
  •  1
  •   Shepmaster Tim Diekmann    7 年前

    在原始代码中

    conn.simple_query("SELECT id, name FROM users").for_each_row(|row| {
        // ...
    }).wait().unwrap();
    

    你说“它可以编译,但可以根据需要挂起。我认为问题出在 wait() 呼叫".

    Future::wait ,您将看到此警告,强调我的警告:

    注意:此方法不适用于调用事件循环或类似的输入/输出情况,因为它会阻止事件循环进行( 这会阻塞线程

    在更新的代码中,您已经

    conn.simple_query("SELECT id, name FROM test").for_each_row(|row| {
        // ...
    });
    

    这构造了一个未来,但随后立即丢弃,因此外部向量不会发生任何变化。期货箱中的所有期货都附有警告,正是出于这个原因:

    我已经提交了 an issue 所以图书馆添加了这个。


    完全未经测试

    extern crate futures;
    extern crate futures_state_stream;
    extern crate tokio_core;
    extern crate tiberius;
    
    use futures::{Future, Stream};
    use futures_state_stream::StateStream;
    use tiberius::SqlConnection;
    use tokio_core::reactor::Core;
    
    fn main() {
        let mut core = Core::new().unwrap();
    
        let connection_string = "server=tcp:127.0.0.1,1433;username=SA;password=qweasdZXC123!!;";
    
        let future = SqlConnection::connect(core.handle(), connection_string)
            .and_then(|conn| {
    
                let query = conn.query("SELECT * FROM test WHERE id > @P1", &[&0i32])
                    .into_stream()
                    .take(1);
    
                query.flatten()
                    .map(|row| {
                        let id: i32 = row.get(0);
                        let name: &str = row.get(1);
    
                        format!("{} - {}", id, name)
                    })
                    .collect()
            });
    
        let all_rows = core.run(future).unwrap();
    .
        println!("{:?}", all_rows);
    }
    

    1. conn.query 可与一起使用 查询语句,因此它返回一个
    2. 康涅狄格州 实际实现了 StateStream futures::Stream . 出于示例的目的,我将其转换回 未来::流 .into_stream() . 这是不理想的,因为我们失去了恢复 conn 之后
    3. 我只取第一个结果集 .take(1)
    4. Stream 流动 Stream::flatten 移除嵌套。
    5. 每行是 map ped到a String
    6. 流动 collect ed成为一个 Future Vec<String>