首页  >  文章  >  数据库  >  介绍 Rust Progra 的 MongoDB 驱动程序

介绍 Rust Progra 的 MongoDB 驱动程序

WBOY
WBOY原创
2016-06-07 16:31:211124浏览

关于黑客新闻的讨论这是 Jao-ke Chin-Lee 和 Jed Estep 的客座帖子,他们目前是 10gen 的实习生。今年夏天,他们的任务是为 MongoDB 构建 Rust 驱动程序。今天我们开源 Mongo 的 alpha 版本

讨论黑客新闻

这是 Jao-ke Chin-Lee 和 Jed Estep 的客座文章,他们目前是 10gen 的实习生。今年夏天,他们的任务是为 MongoDB 构建 Rust 驱动程序。

今天,我们开源了 Rust 编程语言的 MongoDB 驱动程序的 alpha 版本。这是在 Rust 社区的帮助下两个月的工作成果,我们很高兴能够分享我们的初始版本。我们期待来自 Rust 和 MongoDB 社区的反馈。

关于 Rust

Rust 是一种多范式、面向系统的语言,目前 Mozilla 正在开发中。它具有命令式、函数式和面向对象语言的元素,还包括雄心勃勃的新功能,例如允许智能自动内存管理和并发的仿射类型。其强大的类型和内存安全功能在编译时运行,并且仍然保持低级语言的典型性能。随着该语言的不断发展,用本机 Rust 编写的 MongoDB 驱动程序的可用性将 Rust 和 MongoDB 暴露给新的受众。

关于 MongoDB 驱动程序

该驱动程序已获得 Apache 许可,并且纯粹用 Rust 实现,不依赖于任何 C 扩展或库(md5 的嵌入式副本除外,当 Rust 提供本机实现时可以将其删除)。

使用当前 MongoDB 驱动程序的用户会感觉很熟悉该驱动程序。基本 BSON 类型(例如字符串、数字和对象)具有基于 Rust 代数数据类型的内置内部表示。用户还可以实现一个特征(类似于 Haskell 类型类,类似于 Java 接口),该特征允许他们将其代码库的本机类型视为 BSON 的本机类型。

一旦用户的数据被格式化,就可以通过熟悉的对象(如 Collection、DB、Cursor 和 Client)与数据库进行交互。这些对象与其他语言中的对应对象具有相似的 API,目前在 Rust 抽象的框架中提供 CRUD、索引以及管理功能,并平衡 Rust 静态保证的理念与 MongoDB 的灵活性。下面提供了一个小例子。

用法示例

首先我们需要导入 mongo 库和我们将要使用的类。

extern mod mongo;
use mongo::client::*;
use mongo::util::*;
use mongo::coll::*;
use mongo::db::*;

为了与 Mongo 服务器连接,我们首先创建一个客户端。

let client = @Client::new();

要连接到在本地主机端口 27017 (MONGO_DEFAULT_PORT) 上运行的未复制、未分片的服务器,我们使用 connect 方法:

match client.connect(~"127.0.0.1", MONGO_DEFAULT_PORT) {
    Ok(_) => (),
    Err(e) => fail!(e.to_str()),
}

我们在数据库“rust_ex”中创建一个名为“capped”的上限集合,方法是首先创建“rust_ex”数据库的句柄(可能为空,也可能不为空),然后使用指定上限集合大小的参数调用 create_collection (必须不存在)。

let db = DB::new(~"rust_ex", client);
match db.create_collection(~"capped", None, Some(~[CAPPED(100000), MAX_DOCS(20)])) {
    Ok(_) => (),
    Err(e) => fail!(e.to_str()),
};

现在我们创建一个tailable游标来提取“a”字段的值可以被5整除的文档,并投影到“msg”字段上。

let coll = Collection::new(~"rust_ex", ~"capped", client);
let mut cursor = match coll.find(   Some(SpecNotation(~"{ 'a':{'$mod':[5,0]} }")),
                                    Some(SpecNotation(~"{ 'msg':1 }")),
                                    None) {
    Ok(c) => c,     // JSON-formatted strings are automatically converted to BSON
    Err(e) => fail!(e.to_str()),
};
cursor.add_flags(~[CUR_TAILABLE, AWAIT_DATA]);

然后我们生成一个线程来填充上限集合。请注意,对于第一次插入,我们指定 None 作为 writeconcern,这表示默认值 1,而对于后续插入,我们将 writeconcern 指定为 Journaled。

coll.insert(~"{ 'a':0, 'msg':'first insert' }", None);
let n = 50;
do spawn {
    let tmp_client = @Client::new();
    tmp_client.connect(~"127.0.0.1", MONGO_DEFAULT_PORT);
    let coll = Collection::new(~"rust_ex", ~"capped", tmp_client);
    let mut i = 1;
    for n.times {
        match coll.insert(  fmt!("{ 'a':%?, 'msg':'insert no. %?' }", i, i),
                            Some(~[JOURNAL(true)])) {
            Ok(_) => (),
            Err(e) => println(fmt!("%s", e.to_str())),
        };
        i += 1;
    }
    tmp_client.disconnect();
}

同时,在主线程中,我们迭代从 tailable 游标返回的结果。

for 25.times {
    let mut p = cursor.next();
    while p.is_none() && !cursor.is_dead() { p = cursor.next(); }
    if cursor.is_dead() { break; }
    println(fmt!("read %?", p.unwrap().to_str()));
}

最后,我们断开客户端连接。此客户端可以重复使用以连接其他服务器。

match client.disconnect() {
    Ok(_) => (),
    Err(e) => fail!(e.to_str()),
}

有关类似示例,包括将用户实现的结构插入数据库并从数据库读取的工作示例,请参阅示例。

资源

请在 GitHub 存储库中找到更多示例以及我们鼓励您查看和使用的源代码。我们还有可用的文档。请记住,该驱动程序目前仅在 Rust 0.7 版本上构建,并且不适用于其他版本的 Rust。我们欢迎任何反馈和贡献;创建问题或提交拉取请求!

关于我们

MongoDB Rust 驱动程序由 Jao-ke Chin-Lee 和 Jed Estep 开发,他们目前是 10gen 的实习生。我们被 Rust 的创新以及连接 Rust 和 MongoDB 社区的想法所吸引。

致谢

非常感谢 IRC 上的 Rust 社区和 rust-dev 对 Rust 的指导,并开发了如此令人兴奋的语言。特别感谢 10gen 接待我们实习生,Stacy Ferranti 和 Ian Whalen 管理实习计划,感谢我们的导师 Tyler Brock 和 Andrew Morrow 在整个项目过程中提供的帮助和支持。

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn