Alternative ATProto PDS implementation

cargo fix

Changed files
+31 -32
src
+17 -17
src/actor_store/blob/reader.rs
··· 7 7 use crate::config::BlobConfig; 8 8 9 9 /// Reader for blob data in the actor store. 10 - pub struct BlobReader { 10 + pub(super) struct BlobReader { 11 11 /// Database connection. 12 12 pub db: SqlitePool, 13 13 /// Configuration for blob storage. ··· 18 18 19 19 impl BlobReader { 20 20 /// Create a new blob reader. 21 - pub fn new(db: SqlitePool, config: BlobConfig, did: String) -> Self { 21 + pub(super) fn new(db: SqlitePool, config: BlobConfig, did: String) -> Self { 22 22 Self { db, config, did } 23 23 } 24 24 25 25 /// Get metadata for a blob. 26 - pub async fn get_blob_metadata(&self, cid: &Cid) -> Result<Option<BlobMetadata>> { 26 + pub(super) async fn get_blob_metadata(&self, cid: &Cid) -> Result<Option<BlobMetadata>> { 27 27 let cid_str = cid.to_string(); 28 28 let result = sqlx::query!( 29 29 r#"SELECT size, mimeType, takedownRef FROM blob WHERE cid = ?"#, ··· 45 45 } 46 46 47 47 /// Get a blob's full data and metadata. 48 - pub async fn get_blob(&self, cid: &Cid) -> Result<Option<BlobData>> { 48 + pub(super) async fn get_blob(&self, cid: &Cid) -> Result<Option<BlobData>> { 49 49 // First check the metadata 50 50 let metadata = match self.get_blob_metadata(cid).await? { 51 51 Some(meta) => meta, ··· 80 80 } 81 81 82 82 /// List blobs for a repository. 83 - pub async fn list_blobs(&self, opts: ListBlobsOptions) -> Result<Vec<String>> { 83 + pub(super) async fn list_blobs(&self, opts: ListBlobsOptions) -> Result<Vec<String>> { 84 84 let mut query = sqlx::QueryBuilder::new("SELECT cid FROM blob"); 85 85 86 86 // Add filters for since revision ··· 121 121 } 122 122 123 123 /// Get takedown status for a blob. 124 - pub async fn get_blob_takedown_status(&self, cid: &Cid) -> Result<Option<String>> { 124 + pub(super) async fn get_blob_takedown_status(&self, cid: &Cid) -> Result<Option<String>> { 125 125 let cid_str = cid.to_string(); 126 126 let result = sqlx::query!(r#"SELECT takedownRef FROM blob WHERE cid = ?"#, cid_str) 127 127 .fetch_optional(&self.db) ··· 132 132 } 133 133 134 134 /// Get records that reference a blob. 135 - pub async fn get_records_for_blob(&self, cid: &Cid) -> Result<Vec<String>> { 135 + pub(super) async fn get_records_for_blob(&self, cid: &Cid) -> Result<Vec<String>> { 136 136 let cid_str = cid.to_string(); 137 137 let records = sqlx::query!( 138 138 r#"SELECT recordUri FROM record_blob WHERE blobCid = ?"#, ··· 146 146 } 147 147 148 148 /// Get blobs referenced by a record. 149 - pub async fn get_blobs_for_record(&self, record_uri: &str) -> Result<Vec<String>> { 149 + pub(super) async fn get_blobs_for_record(&self, record_uri: &str) -> Result<Vec<String>> { 150 150 let blobs = sqlx::query!( 151 151 r#"SELECT blobCid FROM record_blob WHERE recordUri = ?"#, 152 152 record_uri ··· 159 159 } 160 160 161 161 /// Count total blobs. 162 - pub async fn blob_count(&self) -> Result<i64> { 162 + pub(super) async fn blob_count(&self) -> Result<i64> { 163 163 let result = sqlx::query!(r#"SELECT COUNT(*) as count FROM blob"#) 164 164 .fetch_one(&self.db) 165 165 .await ··· 169 169 } 170 170 171 171 /// Count distinct blobs referenced by records. 172 - pub async fn record_blob_count(&self) -> Result<i64> { 172 + pub(super) async fn record_blob_count(&self) -> Result<i64> { 173 173 let result = sqlx::query!(r#"SELECT COUNT(DISTINCT blobCid) as count FROM record_blob"#) 174 174 .fetch_one(&self.db) 175 175 .await ··· 179 179 } 180 180 181 181 /// List blobs that are referenced but missing from storage. 182 - pub async fn list_missing_blobs( 182 + pub(super) async fn list_missing_blobs( 183 183 &self, 184 184 opts: ListMissingBlobsOptions, 185 185 ) -> Result<Vec<MissingBlob>> { ··· 213 213 } 214 214 215 215 /// Register a new blob in the database (without file storage) 216 - pub async fn register_blob(&self, cid: String, mime_type: String, size: i64) -> Result<()> { 216 + pub(super) async fn register_blob(&self, cid: String, mime_type: String, size: i64) -> Result<()> { 217 217 let now = chrono::Utc::now().to_rfc3339(); 218 218 sqlx::query!( 219 219 r#" ··· 236 236 237 237 /// Metadata about a blob. 238 238 #[derive(Debug, Clone)] 239 - pub struct BlobMetadata { 239 + pub(super) struct BlobMetadata { 240 240 /// The CID of the blob. 241 241 pub cid: Cid, 242 242 /// The size of the blob in bytes. ··· 249 249 250 250 /// Complete blob data with content. 251 251 #[derive(Debug)] 252 - pub struct BlobData { 252 + pub(super) struct BlobData { 253 253 /// Metadata about the blob. 254 254 pub metadata: BlobMetadata, 255 255 /// The actual content of the blob, if available. ··· 258 258 259 259 /// Options for listing blobs. 260 260 #[derive(Debug, Clone)] 261 - pub struct ListBlobsOptions { 261 + pub(super) struct ListBlobsOptions { 262 262 /// Optional revision to list blobs since. 263 263 pub since: Option<String>, 264 264 /// Optional cursor for pagination. ··· 269 269 270 270 /// Options for listing missing blobs. 271 271 #[derive(Debug, Clone)] 272 - pub struct ListMissingBlobsOptions { 272 + pub(super) struct ListMissingBlobsOptions { 273 273 /// Optional cursor for pagination. 274 274 pub cursor: Option<String>, 275 275 /// Maximum number of missing blobs to return. ··· 278 278 279 279 /// Information about a missing blob. 280 280 #[derive(Debug, Clone)] 281 - pub struct MissingBlob { 281 + pub(super) struct MissingBlob { 282 282 /// CID of the missing blob. 283 283 pub cid: String, 284 284 /// URI of the record referencing the missing blob.
+11 -11
src/actor_store/blob/transactor.rs
··· 14 14 15 15 /// Blob metadata for a newly uploaded blob. 16 16 #[derive(Debug, Clone)] 17 - pub struct BlobMetadata { 17 + pub(super) struct BlobMetadata { 18 18 /// Temporary key for the blob during upload. 19 19 pub temp_key: String, 20 20 /// Size of the blob in bytes. ··· 30 30 } 31 31 32 32 /// Transactor for blob operations. 33 - pub struct BlobTransactor { 33 + pub(super) struct BlobTransactor { 34 34 /// The blob reader. 35 35 pub reader: BlobReader, 36 36 /// The blob storage directory. ··· 41 41 42 42 impl BlobTransactor { 43 43 /// Create a new blob transactor. 44 - pub fn new(db: SqlitePool, config: BlobConfig, did: String) -> Self { 44 + pub(super) fn new(db: SqlitePool, config: BlobConfig, did: String) -> Self { 45 45 Self { 46 46 reader: BlobReader::new(db, config.clone(), did), 47 47 blobs_dir: config.path.clone(), ··· 50 50 } 51 51 52 52 /// Register blob associations with records. 53 - pub async fn insert_blobs(&self, record_uri: &str, blobs: &[Blob]) -> Result<()> { 53 + pub(super) async fn insert_blobs(&self, record_uri: &str, blobs: &[Blob]) -> Result<()> { 54 54 if blobs.is_empty() { 55 55 return Ok(()); 56 56 } ··· 84 84 } 85 85 86 86 /// Upload a blob and get its metadata. 87 - pub async fn upload_blob_and_get_metadata( 87 + pub(super) async fn upload_blob_and_get_metadata( 88 88 &self, 89 89 mime_type: &str, 90 90 data: &[u8], ··· 126 126 } 127 127 128 128 /// Track a new blob that's not yet associated with a record. 129 - pub async fn track_untethered_blob(&self, metadata: &BlobMetadata) -> Result<Blob> { 129 + pub(super) async fn track_untethered_blob(&self, metadata: &BlobMetadata) -> Result<Blob> { 130 130 let cid_str = metadata.cid.to_string(); 131 131 132 132 // Check if blob exists and is taken down ··· 178 178 } 179 179 180 180 /// Process blobs for a repository write operation. 181 - pub async fn process_write_blobs( 181 + pub(super) async fn process_write_blobs( 182 182 &self, 183 183 _rev: &str, 184 184 blobs: &[Blob], ··· 197 197 } 198 198 199 199 /// Delete blobs that are no longer referenced by any record. 200 - pub async fn delete_dereferenced_blobs(&self, updated_uris: &[String]) -> Result<()> { 200 + pub(super) async fn delete_dereferenced_blobs(&self, updated_uris: &[String]) -> Result<()> { 201 201 if updated_uris.is_empty() { 202 202 return Ok(()); 203 203 } ··· 279 279 } 280 280 281 281 /// Verify a blob's integrity and move it from temporary to permanent storage. 282 - pub async fn verify_blob_and_make_permanent(&self, blob: &Blob) -> Result<()> { 282 + pub(super) async fn verify_blob_and_make_permanent(&self, blob: &Blob) -> Result<()> { 283 283 let cid_str = blob.r#ref.0.to_string(); 284 284 285 285 // Get blob from database ··· 350 350 } 351 351 352 352 /// Register a blob in the database 353 - pub async fn register_blob(&self, cid: String, mime_type: String, size: u64) -> Result<()> { 353 + pub(super) async fn register_blob(&self, cid: String, mime_type: String, size: u64) -> Result<()> { 354 354 self.reader.register_blob(cid, mime_type, size as i64).await 355 355 } 356 356 357 357 /// Associate a blob with a record 358 - pub async fn associate_blob(&self, cid: &str, record_uri: &str) -> Result<()> { 358 + pub(super) async fn associate_blob(&self, cid: &str, record_uri: &str) -> Result<()> { 359 359 sqlx::query!( 360 360 r#" 361 361 INSERT INTO record_blob (blobCid, recordUri)
+1 -1
src/actor_store/db/migrations.rs
··· 1 1 //! Database migrations for the actor store. 2 - use anyhow::{Context as _, Result}; 2 + use anyhow::Result; 3 3 4 4 use crate::actor_store::db::ActorDb; 5 5
-1
src/actor_store/db/mod.rs
··· 236 236 } 237 237 238 238 // Re-export commonly used types 239 - pub(crate) use schema::{AccountPref, Backlink, Blob, Record, RecordBlob, RepoBlock, RepoRoot};
+2 -2
src/actor_store/mod.rs
··· 8 8 use std::sync::Arc; 9 9 10 10 use anyhow::{Context as _, Result}; 11 - use atrium_crypto::keypair::{Did as _, Export as _, Secp256k1Keypair}; 11 + use atrium_crypto::keypair::{Export as _, Secp256k1Keypair}; 12 12 use sqlx::SqlitePool; 13 13 14 14 use crate::config::RepoConfig; ··· 222 222 .context("failed to create SQLite database")?; 223 223 224 224 // Create database schema 225 - self::db::create_tables(&db).await?; 225 + db::create_tables(&db).await?; 226 226 227 227 Ok(()) 228 228 }