|
| 1 | +# closure-tree (Rust) |
| 2 | + |
| 3 | +A SeaORM-friendly port of Ruby's [`closure_tree`](https://github.com/ClosureTree/closure_tree). |
| 4 | + |
| 5 | +## Status |
| 6 | + |
| 7 | +Early preview (`0.0.1`). PostgreSQL only. Contributions welcome. |
| 8 | + |
| 9 | +## Quickstart |
| 10 | + |
| 11 | +```toml |
| 12 | +[dependencies] |
| 13 | +closure-tree = "0.0.1" |
| 14 | +``` |
| 15 | + |
| 16 | +```rust |
| 17 | +use closure_tree::ClosureTreeRepository; |
| 18 | +use closure_tree::ClosureTreeModelDerive as ClosureTreeModel; |
| 19 | +use sea_orm::entity::prelude::*; |
| 20 | + |
| 21 | +#[derive(Clone, Debug, PartialEq, DeriveEntityModel, ClosureTreeModel)] |
| 22 | +#[sea_orm(table_name = "nodes")] |
| 23 | +#[closure_tree(hierarchy_module = "crate::entity::node_hierarchy", hierarchy_table = "node_hierarchies")] |
| 24 | +pub struct Model { |
| 25 | + #[sea_orm(primary_key)] |
| 26 | + pub id: i32, |
| 27 | + pub parent_id: Option<i32>, |
| 28 | + pub name: String, |
| 29 | +} |
| 30 | + |
| 31 | +#[tokio::main] |
| 32 | +async fn main() -> Result<(), Box<dyn std::error::Error>> { |
| 33 | + let db = sea_orm::Database::connect("postgres://...").await?; |
| 34 | + let repo = ClosureTreeRepository::<entity::node::Model>::new(); |
| 35 | + |
| 36 | + let _leaf = repo |
| 37 | + .find_or_create_by_path(&db, &["root", "child", "leaf"]) |
| 38 | + .await?; |
| 39 | + |
| 40 | + Ok(()) |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +## Features |
| 45 | + |
| 46 | +* Derive macro for SeaORM models (`#[derive(ClosureTreeModel)]`). |
| 47 | +* Repository helpers (`parent`, `descendants`, `find_by_path`, `find_or_create_by_path`, etc.). |
| 48 | +* Advisory locks via `pg_advisory_lock`, rebuild utilities. |
| 49 | +* Integration test against a Docker Postgres instance. |
| 50 | + |
| 51 | +## Limitations |
| 52 | + |
| 53 | +* PostgreSQL only. |
| 54 | +* Ordering, `hash_tree`, dependent strategies, and some Ruby APIs are not yet ported. |
| 55 | +* Advisory lock is limited to Postgres advisory locks; no MySQL adapter yet. |
| 56 | + |
| 57 | +## Development |
| 58 | + |
| 59 | +``` |
| 60 | +cargo fmt |
| 61 | +cargo clippy --all-targets -- -D warnings |
| 62 | +cargo test |
| 63 | +``` |
| 64 | + |
| 65 | +Requires Docker Postgres at `postgres://closure_tree:closure_tree_pass@localhost:5434/closure_tree_test` (see `tests/postgres.rs`). |
0 commit comments