我需要使用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();
}
此代码打印一个空向量,但我需要完整的字符串向量。我读过一些关于期货的文章,但就像Rust的新手一样,它们对我来说太复杂了。
答案 0 :(得分:1)
在原始代码中,您有
conn.simple_query("SELECT id, name FROM users").for_each_row(|row| {
// ...
}).wait().unwrap();
你说&#34;它编译但是根据要求挂起。我认为wait()
调用问题。&#34;。
如果你阅读了Future::wait
的文档,你会看到这个警告,强调我的:
注意:此方法不适合调用事件循环或类似的I / O情况,因为它会阻止事件循环取得进展(这会阻塞线程)。只有在保证与此未来相关的阻止工作将由另一个线程完成时,才应调用此方法。
在更新的代码中,您有
conn.simple_query("SELECT id, name FROM test").for_each_row(|row| {
// ...
});
这构建了一个未来,但随后立即将其丢弃,因此外部向量不会发生任何事情。由于这个原因,期货箱中的所有期货都附有警告:
警告:未使用的`期货:: FutureResult`必须使用:除非进行轮询,否则期货什么都不做
我已提交an issue,以便图书馆添加此内容。
这是完全未经测试的代码段。我没有一个SQL Server实例来实际测试它,但它确实编译并具有正确的形状。
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);
}
重点:
conn.query
可与多个查询语句一起使用,因此它会返回结果集的流。conn.query
实际上实现了StateStream
,而不是futures::Stream
。出于示例的目的,我将其转换回futures::Stream
.into_stream()
。这是不理想的,因为我们之后无法恢复conn
。.take(1)
的第一个结果集。Stream
Stream
,我们使用Stream::flatten
删除嵌套。map
到String
。Stream
被collect
加入Future
Vec<String>
个 #include <stdio.h>
#include <stdlib.h>
void CreateFile(FILE *file){
file = fopen("file.txt","w");
if(file == NULL){
printf("Error : Could not create the file");
}
}
void WriteFile(FILE *file){
fprintf(file,"Hello !");
}
int main()
{
FILE *file = NULL;
CreateFile(file);
WriteFile(file);
fclose(file);
return 0;
}
醇>