Rust分布式应用数据存储库holochain_state的使用:高效管理Holochain生态链状态与持久化数据

Rust分布式应用数据存储库holochain_state的使用:高效管理Holochain生态链状态与持久化数据

holochain_state crate提供了与holochain_sqlite crate协同工作的辅助工具和抽象层。

读取操作

创建数据读取查询的主要抽象是Query trait。这个trait可以用于简化复杂查询的构建。

source_chain模块提供了SourceChain类型,这是用于处理操作链的抽象层。

host_fn_workspace模块提供了在工作流期间读取数据的抽象。

写入操作

mutations模块是用于将数据写入sqlite的完整函数集。

内存操作

scratch模块提供了Scratch类型,用于读取和写入内存中不可见的数据。

SourceChain类型使用Scratch进行内存操作,这些操作可以刷新到数据库。

Query trait允许将任意数据库SQL查询与暂存空间结合,因此读取可以跨越数据库和内存数据。

完整示例代码

use holochain_state::{prelude::*, source_chain::SourceChain};

// 示例1: 使用Query trait进行复杂查询
struct MyQuery;
impl Query for MyQuery {
    type Output = Vec<ActionHash>;
    
    fn query(&self, db: &DbRead) -> StateQueryResult<Self::Output> {
        // 实现自定义查询逻辑
        Ok(vec![])
    }
}

// 示例2: 使用SourceChain管理链状态
async fn manage_source_chain() -> StateMutationResult<()> {
    let env = holochain_state::test_utils::test_environments();
    let db = env.guard();
    
    let mut source_chain = SourceChain::new(db.clone())?;
    
    // 添加新操作到链中
    let action_hash = source_chain.put_action(Action::Dna(DnaDef::default()))?;
    
    // 从链中读取操作
    let action = source_chain.get_action(&action_hash)?;
    
    Ok(())
}

// 示例3: 使用Scratch进行内存操作
async fn use_scratch() -> StateMutationResult<()> {
    let env = holochain_state::test_utils::test_environments();
    let db = env.guard();
    let scratch = Scratch::new();
    
    // 在scratch中写入数据
    scratch.insert_hash("key".into(), "value".into());
    
    // 从scratch读取数据
    let value = scratch.get_hash("key")?;
    
    // 将scratch数据写入数据库
    scratch.flush(&db)?;
    
    Ok(())
}

扩展完整示例

以下是一个结合了所有主要功能的完整示例:

use holochain_state::{
    prelude::*,
    source_chain::SourceChain,
    scratch::Scratch,
    mutations,
};

// 自定义查询结构体
struct RecentActionsQuery {
    limit: usize,
}

impl Query for RecentActionsQuery {
    type Output = Vec<Action>;
    
    fn query(&self, db: &DbRead) -> StateQueryResult<Self::Output> {
        // 查询最近的操作
        let actions = db.prepare("SELECT * FROM Action ORDER BY timestamp DESC LIMIT ?")?
            .query_map([self.limit], |row| {
                Ok(Action::from_row(row)?)
            })?
            .collect::<Result<Vec<_>, _>>()?;
        Ok(actions)
    }
}

async fn comprehensive_example() -> StateMutationResult<()> {
    // 初始化测试环境
    let env = holochain_state::test_utils::test_environments();
    let db = env.guard();
    
    // 1. 使用SourceChain管理链状态
    let mut source_chain = SourceChain::new(db.clone())?;
    let scratch = Scratch::new();
    
    // 2. 添加操作到链中
    let action1 = Action::Dna(DnaDef::default());
    let hash1 = source_chain.put_action(action1.clone())?;
    
    // 3. 使用scratch进行内存操作
    scratch.insert_hash(hash1.clone(), "metadata1".into());
    
    // 4. 查询操作
    let recent_actions = RecentActionsQuery { limit: 10 }.query(&db)?;
    
    // 5. 将scratch数据写入数据库
    scratch.flush(&db)?;
    
    // 6. 使用mutations进行直接写入
    mutations::insert_action(&db, Action::Dna(DnaDef::default()))?;
    
    Ok(())
}

#[tokio::main]
async fn main() {
    comprehensive_example().await.expect("示例运行失败");
}

许可证

CAL-1.0许可证

版权所有 © 2019 - 2024, Holochain Foundation

本程序是自由软件:您可以在LICENSE文件(CAL-1.0)提供的许可条款下重新分发和/或修改它。本程序分发时希望它会有用,但没有任何担保;甚至没有适销性或特定用途适用性的暗示担保。


1 回复

Rust分布式应用数据存储库holochain_state使用指南

概述

holochain_state是一个用于Holochain生态系统的Rust数据存储库,专门用于高效管理分布式应用的状态和持久化数据。它为Holochain应用提供了可靠的数据存储和检索机制,是构建去中心化应用(DApp)的重要组件。

主要特性

  • 为Holochain应用提供本地数据存储
  • 高效的状态管理
  • 数据持久化支持
  • 与Holochain运行时深度集成
  • 支持事务操作

使用方法

添加依赖

首先在Cargo.toml中添加依赖:

[dependencies]
holochain_state = "0.1"  # 请使用最新版本

基本使用示例

use holochain_state::{prelude::*, buffer::Buffer};
use holochain_zome_types::element::Element;

// 创建新的数据库
let env = holochain_state::env::Environment::new().unwrap();
let db = env.db().unwrap();

// 创建缓冲区用于批量操作
let mut buffer = Buffer::new(db.clone()).unwrap();

// 创建并存储一个元素
let element: Element = create_some_element(); // 假设的创建元素函数
buffer.put(&element).unwrap();

// 提交事务
buffer.flush().unwrap();

// 查询元素
let retrieved: Option<Element> = db.read(|reader| {
    holochain_state::query::get_element(&reader, &element.header().address()).unwrap()
}).unwrap();

状态管理

use holochain_state::prelude::*;

// 初始化状态
let state = holochain_state::State::new(env).unwrap();

// 获取状态快照
let snapshot = state.snapshot().unwrap();

// 使用快照查询数据
let all_elements: Vec<Element> = snapshot.arena().get_all_elements().unwrap();

高级查询

use holochain_state::query::Query;

// 创建查询
let query = Query::new()
    .include_entries(true)
    .entry_type("my_entry_type".to_string());

// 执行查询
let results = db.read(|reader| {
    query.run(&reader).unwrap()
}).unwrap();

完整示例demo

下面是一个完整的holochain_state使用示例,包含了创建数据库、存储数据、查询数据和状态管理等操作:

use holochain_state::{prelude::*, buffer::Buffer, env::Environment};
use holochain_zome_types::element::{Element, ElementHeader, Entry};

fn main() -> anyhow::Result<()> {
    // 1. 创建数据库环境
    let env = Environment::new()?;
    let db = env.db()?;
    
    // 2. 创建示例元素
    let entry = Entry::App("example_data".into());
    let header = ElementHeader::new("my_entry_type".into());
    let element = Element::new(header, entry);
    
    // 3. 使用缓冲区存储元素
    let mut buffer = Buffer::new(db.clone())?;
    buffer.put(&element)?;
    buffer.flush()?;
    
    // 4. 查询元素
    let retrieved: Option<Element> = db.read(|reader| {
        holochain_state::query::get_element(&reader, &element.header().address())
    })??;
    
    println!("检索到的元素: {:?}", retrieved);
    
    // 5. 状态管理示例
    let state = holochain_state::State::new(env)?;
    let snapshot = state.snapshot()?;
    
    // 6. 使用快照查询所有元素
    let all_elements: Vec<Element> = snapshot.arena().get_all_elements()?;
    println!("当前存储的所有元素数量: {}", all_elements.len());
    
    // 7. 高级查询示例
    let query = Query::new()
        .include_entries(true)
        .entry_type("my_entry_type".to_string());
        
    let results = db.read(|reader| query.run(&reader))??;
    println!("查询结果数量: {}", results.len());
    
    Ok(())
}

最佳实践

  1. 使用事务:尽可能使用Buffer进行批量操作,减少I/O开销
  2. 合理使用快照:对于需要一致性的读取操作,使用状态快照
  3. 索引优化:为常用查询字段创建索引
  4. 资源管理:及时关闭数据库连接和事务

注意事项

  • holochain_state主要设计用于Holochain应用上下文
  • 在多线程环境中使用时需要注意线程安全
  • 数据库操作可能会失败,应适当处理错误

holochain_state为Holochain应用提供了强大的底层存储能力,通过合理使用可以构建高效可靠的分布式应用程序。

回到顶部