4个版本
0.1.0-alpha.3 | 2019年12月8日 |
---|---|
0.1.0-alpha.2 | 2019年11月28日 |
0.1.0-alpha.1 | 2019年11月27日 |
#51 in #atom
76KB
1.5K SLoC
g1
简单的图存储。
模型
原子:原子是图中的节点。每个原子都表示为一个UUID。
名称:名称唯一标识一个原子。它们有一个命名空间和一个标题,两者都是字符串。
边:边是定向的,两端都有一个原子。边与一个字符串标签相关联。两个具有给定标签的原子之间最多只能存在一条边。
标签:标签附加到原子上。它们有一个键和一个值,两者都是字符串。
Blob:Blob附加到原子上。它们有一个类型,这是一个字符串;一个类型,这是一个MIME类型;以及内容,这是一个任意大小的二进制字符串。Blob通过SHA256散列来引用。
字符串是UTF-8字符串,长度不应超过256字节。
Rust API
目前,只实现了简单操作
use anyhow::{anyhow, Result};
use defer::defer;
use futures::prelude::*;
use g1::{query, Atom, Connection, SqliteConnection};
#[tokio::main]
async fn main() -> Result<()> {
let mut db_dir = std::env::temp_dir();
db_dir.push("g1-readme-example");
std::fs::create_dir_all(&db_dir)?;
let _guard = defer(|| {
std::fs::remove_dir_all(&db_dir).unwrap();
});
let conn = SqliteConnection::open(db_dir.clone()).await?;
conn.create_name(conn.create_atom().await?, "example/readme", "foo", false)
.await?;
conn.create_name(conn.create_atom().await?, "example/readme", "bar", false)
.await?;
let foo = conn
.query_first(query! { ?- name(Atom, "example/readme", "foo"). })
.await?
.ok_or_else(|| anyhow!("couldn't find foo"))?[0]
.parse()?;
let bar = conn
.query_first(query! { ?- name(Atom, "example/readme", "bar"). })
.await?
.ok_or_else(|| anyhow!("couldn't find bar"))?[0]
.parse()?;
conn.create_name(bar, "other namespace", "bar", false)
.await?;
assert_eq!(
conn.query_first(query! { ?- name(Atom, "other namespace", "bar"). })
.await?
.ok_or_else(|| anyhow!("couldn't find bar"))?[0]
.parse::<Atom>()?,
bar
);
conn.create_edge(foo, bar, "next").await?;
conn.create_edge(bar, foo, "prev").await?;
let edges = conn.query_all(query! { ?- edge(From, To, Label). }).await?;
assert!(edges.contains(&vec![
foo.to_string().into(),
bar.to_string().into(),
"next".to_string().into()
]));
assert!(edges.contains(&vec![
bar.to_string().into(),
foo.to_string().into(),
"prev".to_string().into()
]));
conn.create_tag(foo, "letters", "3", false).await?;
let hash = conn
.store_blob(stream::once(future::ok((b"bar" as &[_]).into())).boxed())
.await?;
conn.create_blob(
bar,
"name again",
"text/plain".parse().unwrap(),
hash,
false,
)
.await?;
Ok(())
}
依赖关系
~8–13MB
~212K SLoC