From 2f8ecd482077d82f2d1a937c7f979eaaa87a27b2 Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Wed, 3 Dec 2025 08:54:00 +0000 Subject: feat: implement LMDB database backend - Add nostr-lmdb dependency (v0.44) for persistent storage - Create SharedDatabase type alias for database abstraction - Update all database-related functions to use trait object - Support runtime selection via NGIT_DATABASE_BACKEND env var Database backends: - memory: In-memory (default, fastest, no persistence) - lmdb: LMDB backend (persistent, general purpose) All 34 tests pass with the new implementation. --- src/git/authorization.rs | 12 ++++++------ src/git/handlers.rs | 7 +++---- 2 files changed, 9 insertions(+), 10 deletions(-) (limited to 'src/git') diff --git a/src/git/authorization.rs b/src/git/authorization.rs index 3b0e759..4896fc0 100644 --- a/src/git/authorization.rs +++ b/src/git/authorization.rs @@ -31,9 +31,9 @@ use anyhow::{anyhow, Result}; use nostr_relay_builder::prelude::*; use nostr_sdk::{EventId, ToBech32}; use std::collections::{HashMap, HashSet}; -use std::sync::Arc; use tracing::debug; +use crate::nostr::builder::SharedDatabase; use crate::nostr::events::{ RepositoryAnnouncement, RepositoryState, KIND_PR, KIND_PR_UPDATE, KIND_REPOSITORY_ANNOUNCEMENT, KIND_REPOSITORY_STATE, @@ -56,7 +56,7 @@ pub struct RepositoryData { /// This performs a single database query to fetch both announcement and state events, /// which is more efficient than separate queries. pub async fn fetch_repository_data( - database: &Arc, + database: &SharedDatabase, identifier: &str, ) -> Result { let filter = Filter::new() @@ -284,7 +284,7 @@ pub fn is_latest_state( /// /// Returns an `AuthorizationResult` that indicates whether a push is authorized. pub async fn get_authorization_from_db( - database: &Arc, + database: &SharedDatabase, identifier: &str, ) -> Result { // Fetch all repository data with a single query @@ -340,7 +340,7 @@ pub async fn get_authorization_from_db( /// /// Returns an `AuthorizationResult` that indicates whether a push is authorized. pub async fn get_authorization_for_owner( - database: &Arc, + database: &SharedDatabase, identifier: &str, owner_pubkey: &str, ) -> Result { @@ -817,7 +817,7 @@ pub fn npub_to_pubkey(npub: &str) -> Result { /// - `Ok(None)` if the event doesn't exist (push should be allowed) /// - `Err(_)` on database errors pub async fn get_event_commit_tag( - database: &Arc, + database: &SharedDatabase, event_id: &EventId, ) -> Result> { // Query for PR (1618) and PR Update (1619) events with this ID @@ -872,7 +872,7 @@ pub async fn get_event_commit_tag( /// * `Ok(())` if all refs/nostr/ pushes are valid /// * `Err(_)` if any ref has invalid event ID format or fails commit validation pub async fn validate_nostr_ref_pushes( - database: &Arc, + database: &SharedDatabase, pushed_refs: &[(String, String, String)], ) -> Result<()> { for (_, new_oid, ref_name) in pushed_refs { diff --git a/src/git/handlers.rs b/src/git/handlers.rs index e84cabb..8e5f5e1 100644 --- a/src/git/handlers.rs +++ b/src/git/handlers.rs @@ -4,9 +4,7 @@ use http_body_util::Full; use hyper::{body::Bytes, Response, StatusCode}; -use nostr_relay_builder::prelude::MemoryDatabase; use std::path::PathBuf; -use std::sync::Arc; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tracing::{debug, error, info, warn}; @@ -18,6 +16,7 @@ use super::protocol::{GitService, PktLine}; use super::subprocess::GitSubprocess; use super::try_set_head_if_available; +use crate::nostr::builder::SharedDatabase; use crate::nostr::events::RepositoryState; /// Handle GET /info/refs?service=git-{upload,receive}-pack @@ -178,7 +177,7 @@ pub async fn handle_upload_pack( pub async fn handle_receive_pack( repo_path: PathBuf, request_body: Bytes, - database: Option>, + database: Option, identifier: &str, owner_pubkey: &str, ) -> Result>, GitError> { @@ -310,7 +309,7 @@ pub async fn handle_receive_pack( /// 5. Validates that pushed refs match the state /// 6. Validates refs/nostr/ has valid event id and if event exists, `c` tag matches ref async fn authorize_push( - database: &Arc, + database: &SharedDatabase, identifier: &str, owner_pubkey: &str, request_body: &Bytes, -- cgit v1.2.3