wip: Custom mirroring tangled knot written in Rust
rust tangled mirror knot
1

Configure Feed

Select the types of activity you want to include in your feed.

rpc(create/list): store repo metatdata in sqlite

Clément (Jun 15, 2026, 10:53 PM +0200) 6bed3d10 c9042a4a

+62 -15
+20
.sqlx/query-025a0cdb4496cf658003470529e499a78290687b63c95a2905bdc01aeea4ec89.json
··· 1 + { 2 + "db_name": "SQLite", 3 + "query": "select repo_did from repo", 4 + "describe": { 5 + "columns": [ 6 + { 7 + "name": "repo_did", 8 + "ordinal": 0, 9 + "type_info": "Text" 10 + } 11 + ], 12 + "parameters": { 13 + "Right": 0 14 + }, 15 + "nullable": [ 16 + false 17 + ] 18 + }, 19 + "hash": "025a0cdb4496cf658003470529e499a78290687b63c95a2905bdc01aeea4ec89" 20 + }
+12
.sqlx/query-16e962acb1b3f79f141d49c893c3d777310f4c3943f148af93bd0afdebea7df0.json
··· 1 + { 2 + "db_name": "SQLite", 3 + "query": "insert into repo (repo_did, owner_did, rkey, name, source, created_at)\n values (?, ?, ?, ?, ?, datetime('now'))", 4 + "describe": { 5 + "columns": [], 6 + "parameters": { 7 + "Right": 5 8 + }, 9 + "nullable": [] 10 + }, 11 + "hash": "16e962acb1b3f79f141d49c893c3d777310f4c3943f148af93bd0afdebea7df0" 12 + }
+21
crates/knotty-knot/src/xrpc/knotty/create.rs
··· 71 71 KnotError::internal(e) 72 72 })?; 73 73 74 + let repo_did_str = repo_did.as_str(); 75 + let actor_did_str = actor_did.as_str(); 76 + let rkey = req.rkey.as_ref(); 77 + let name = req.name.as_ref(); 78 + let source = req.source.as_ref(); 79 + sqlx::query!( 80 + "insert into repo (repo_did, owner_did, rkey, name, source, created_at) 81 + values (?, ?, ?, ?, ?, datetime('now'))", 82 + repo_did_str, 83 + actor_did_str, 84 + rkey, 85 + name, 86 + source 87 + ) 88 + .execute(&state.db) 89 + .await 90 + .map_err(|e| { 91 + tracing::error!(did = %repo_did, error = %e, "failed to insert repo into database"); 92 + KnotError::internal(e) 93 + })?; 94 + 74 95 Ok(Json(CreateOutput { 75 96 repo_did: repo_did.into_static(), 76 97 extra_data: Default::default(),
+9 -15
crates/knotty-knot/src/xrpc/knotty/list.rs
··· 7 7 pub async fn handler( 8 8 State(state): State<KnotState>, 9 9 ) -> Result<Json<ListOutput<'static>>, KnotError> { 10 - let dir = match std::fs::read_dir(state.storage_path) { 11 - Ok(dir) => dir, 12 - Err(err) => { 13 - tracing::info!(error = %err, "storage path is unreachable"); 14 - return Ok(Json(ListOutput { 15 - repos: Vec::new(), 16 - extra_data: Default::default(), 17 - })); 18 - } 19 - }; 10 + let rows = sqlx::query!("select repo_did from repo") 11 + .fetch_all(&state.db) 12 + .await 13 + .map_err(|e| { 14 + tracing::error!(error = %e, "failed to query repos from database"); 15 + KnotError::internal(e) 16 + })?; 20 17 21 - let repos: Vec<_> = dir 18 + let repos = rows 22 19 .into_iter() 23 - .flatten() 24 - .filter(|entry| entry.file_type().map_or(false, |ft| ft.is_dir())) 25 - .map(|entry| entry.file_name().to_string_lossy().to_string()) 26 - .filter_map(|entry| Did::new_owned(entry).ok()) 20 + .filter_map(|row| Did::new_owned(row.repo_did).ok()) 27 21 .map(|repo_did| Repo { 28 22 repo_did, 29 23 extra_data: Default::default(),