From 927be286e8ca8c4f2c64ec98cfb20e8161aaa96e Mon Sep 17 00:00:00 2001 From: kaichaosun Date: Mon, 30 Mar 2026 12:44:26 +0800 Subject: [PATCH] chore: sqlite rename --- Cargo.lock | 24 +-- Cargo.toml | 2 +- core/conversations/Cargo.toml | 2 +- core/conversations/src/api.rs | 2 +- core/conversations/src/context.rs | 150 +++--------------- core/conversations/src/inbox/handler.rs | 4 +- core/conversations/src/lib.rs | 2 +- core/{chat-sqlite => sqlite}/Cargo.toml | 2 +- core/{chat-sqlite => sqlite}/src/lib.rs | 9 +- .../{chat-sqlite => sqlite}/src/migrations.rs | 0 .../src/migrations/001_initial_schema.sql | 0 core/{chat-sqlite => sqlite}/src/types.rs | 0 12 files changed, 47 insertions(+), 150 deletions(-) rename core/{chat-sqlite => sqlite}/Cargo.toml (93%) rename core/{chat-sqlite => sqlite}/src/lib.rs (98%) rename core/{chat-sqlite => sqlite}/src/migrations.rs (100%) rename core/{chat-sqlite => sqlite}/src/migrations/001_initial_schema.sql (100%) rename core/{chat-sqlite => sqlite}/src/types.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 47a7dc7..0a4ad41 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,17 +108,6 @@ dependencies = [ "prost", ] -[[package]] -name = "chat-sqlite" -version = "0.1.0" -dependencies = [ - "crypto", - "hex", - "storage", - "tempfile", - "zeroize", -] - [[package]] name = "cipher" version = "0.4.4" @@ -513,13 +502,13 @@ dependencies = [ "base64", "blake2", "chat-proto", - "chat-sqlite", "crypto", "double-ratchets", "hex", "prost", "rand_core", "safer-ffi", + "sqlite", "storage", "tempfile", "thiserror", @@ -902,6 +891,17 @@ dependencies = [ "der", ] +[[package]] +name = "sqlite" +version = "0.1.0" +dependencies = [ + "crypto", + "hex", + "storage", + "tempfile", + "zeroize", +] + [[package]] name = "stabby" version = "36.2.2" diff --git a/Cargo.toml b/Cargo.toml index 161cf69..3702b53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = [ - "core/chat-sqlite", + "core/sqlite", "core/conversations", "core/crypto", "core/double-ratchets", diff --git a/core/conversations/Cargo.toml b/core/conversations/Cargo.toml index 62f8f87..fe47d4b 100644 --- a/core/conversations/Cargo.toml +++ b/core/conversations/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["rlib","staticlib","dylib"] [dependencies] base64 = "0.22" -chat-sqlite = { path = "../chat-sqlite" } +sqlite = { path = "../sqlite" } blake2.workspace = true chat-proto = { git = "https://github.com/logos-messaging/chat_proto" } crypto = { path = "../crypto" } diff --git a/core/conversations/src/api.rs b/core/conversations/src/api.rs index 3daaf4a..5bcd371 100644 --- a/core/conversations/src/api.rs +++ b/core/conversations/src/api.rs @@ -13,7 +13,7 @@ use safer_ffi::{ prelude::{c_slice, repr_c}, }; -use chat_sqlite::ChatStorage; +use sqlite::ChatStorage; use storage::StorageConfig; use crate::{ diff --git a/core/conversations/src/context.rs b/core/conversations/src/context.rs index 04a8ec1..49b9a3a 100644 --- a/core/conversations/src/context.rs +++ b/core/conversations/src/context.rs @@ -1,12 +1,10 @@ use std::rc::Rc; use std::sync::Arc; -use chat_sqlite::ChatStorage; use crypto::Identity; use double_ratchets::{RatchetState, RatchetStorage}; -use storage::{ - ChatStore, ConversationKind, ConversationMeta, IdentityStore, StorageConfig, -}; +use sqlite::ChatStorage; +use storage::{ChatStore, ConversationKind, ConversationMeta, IdentityStore, StorageConfig}; use crate::{ conversation::{ConversationId, Convo, Id, PrivateV1Convo}, @@ -24,7 +22,7 @@ pub use crate::inbox::Introduction; pub struct Context { _identity: Rc, inbox: Inbox, - storage: T, + store: T, ratchet_storage: RatchetStorage, } @@ -57,7 +55,7 @@ impl Context { Ok(Self { _identity: identity, inbox, - storage: store, + store, ratchet_storage, }) } @@ -95,7 +93,7 @@ impl Context { } pub fn list_conversations(&self) -> Result, ChatError> { - let records = self.storage.load_conversations()?; + let records = self.store.load_conversations()?; Ok(records .into_iter() .map(|r| Arc::from(r.local_convo_id.as_str())) @@ -128,7 +126,7 @@ impl Context { let enc = EncryptedPayload::decode(env.payload)?; match convo_id { c if c == self.inbox.id() => self.dispatch_to_inbox(enc), - c if self.storage.has_conversation(&c)? => self.dispatch_to_convo(&c, enc), + c if self.store.has_conversation(&c)? => self.dispatch_to_convo(&c, enc), _ => Ok(None), } } @@ -141,14 +139,14 @@ impl Context { // Look up the ephemeral key from storage let key_hex = Inbox::extract_ephemeral_key_hex(&enc_payload)?; let ephemeral_key = self - .storage + .store .load_ephemeral_key(&key_hex)? .ok_or(ChatError::UnknownEphemeralKey())?; let (convo, content) = self.inbox.handle_frame(&ephemeral_key, enc_payload)?; // Remove consumed ephemeral key from storage - self.storage.remove_ephemeral_key(&key_hex)?; + self.store.remove_ephemeral_key(&key_hex)?; self.persist_convo(convo.as_ref()); Ok(content) @@ -170,7 +168,7 @@ impl Context { pub fn create_intro_bundle(&mut self) -> Result, ChatError> { let (intro, public_key_hex, private_key) = self.inbox.create_intro_bundle(); - self.storage + self.store .save_ephemeral_key(&public_key_hex, &private_key)?; Ok(intro.into()) } @@ -178,7 +176,7 @@ impl Context { /// Loads a conversation from DB by constructing it from metadata + ratchet state. fn load_convo(&self, convo_id: ConversationId) -> Result { let record = self - .storage + .store .load_conversation(convo_id)? .ok_or_else(|| ChatError::NoConvo(convo_id.into()))?; @@ -208,124 +206,22 @@ impl Context { remote_convo_id: convo.remote_id(), kind: convo.convo_type().into(), }; - let _ = self.storage.save_conversation(&convo_info); + let _ = self.store.save_conversation(&convo_info); let _ = convo.save_ratchet_state(&mut self.ratchet_storage); Arc::from(convo.id()) } } -#[cfg(test)] -mod mock { - use crypto::PrivateKey; - use storage::{ - ConversationStore, EphemeralKeyStore, IdentityStore, StorageError, - }; - - use super::*; - use std::collections::HashMap; - use std::sync::Mutex; - - // Simple in-memory implementation of ChatStore for tests. - // Adjust the methods to match the exact trait definition in `crate::store::ChatStore`. - #[derive(Default)] - pub struct MockChatStore { - identity: Option, - conversations: Mutex>, - ephemeral_keys: Mutex>, - } - - impl IdentityStore for MockChatStore { - fn load_identity(&self) -> Result, StorageError> { - Ok(self.identity.clone()) - } - - fn save_identity(&mut self, identity: &Identity) -> Result<(), StorageError> { - self.identity = Some(identity.clone()); - Ok(()) - } - } - - impl EphemeralKeyStore for MockChatStore { - fn load_ephemeral_key(&self, key_hex: &str) -> Result, StorageError> { - Ok(self.ephemeral_keys.lock().unwrap().get(key_hex).cloned()) - } - - fn save_ephemeral_key( - &mut self, - key_hex: &str, - private_key: &PrivateKey, - ) -> Result<(), StorageError> { - self.ephemeral_keys - .lock() - .unwrap() - .insert(key_hex.to_string(), private_key.clone()); - Ok(()) - } - - fn remove_ephemeral_key(&mut self, key_hex: &str) -> Result<(), StorageError> { - self.ephemeral_keys.lock().unwrap().remove(key_hex); - Ok(()) - } - } - - impl ConversationStore for MockChatStore { - fn save_conversation(&mut self, meta: &ConversationMeta) -> Result<(), StorageError> { - self.conversations - .lock() - .unwrap() - .insert(meta.local_convo_id.clone(), meta.clone()); - Ok(()) - } - - fn load_conversation( - &self, - local_convo_id: &str, - ) -> Result, StorageError> { - Ok(self - .conversations - .lock() - .unwrap() - .get(local_convo_id) - .cloned()) - } - - fn remove_conversation(&mut self, local_convo_id: &str) -> Result<(), StorageError> { - self.conversations.lock().unwrap().remove(local_convo_id); - Ok(()) - } - - fn load_conversations(&self) -> Result, StorageError> { - Ok(self - .conversations - .lock() - .unwrap() - .values() - .cloned() - .collect()) - } - - fn has_conversation(&self, local_convo_id: &str) -> Result { - Ok(self - .conversations - .lock() - .unwrap() - .contains_key(local_convo_id)) - } - } -} - #[cfg(test)] mod tests { - use chat_sqlite::ChatStorage; + use sqlite::ChatStorage; use storage::ConversationStore; - use crate::context::mock::MockChatStore; - use super::*; fn send_and_verify( - sender: &mut Context, - receiver: &mut Context, + sender: &mut Context, + receiver: &mut Context, convo_id: ConversationId, content: &[u8], ) { @@ -341,8 +237,8 @@ mod tests { #[test] fn ctx_integration() { - let mut saro = Context::new_with_name("saro", MockChatStore::default()); - let mut raya = Context::new_with_name("raya", MockChatStore::default()); + let mut saro = Context::new_with_name("saro", ChatStorage::in_memory()); + let mut raya = Context::new_with_name("raya", ChatStorage::in_memory()); // Raya creates intro bundle and sends to Saro let bundle = raya.create_intro_bundle().unwrap(); @@ -383,12 +279,12 @@ mod tests { .to_string(); let config = StorageConfig::File(db_path); - let ctx1 = Context::open("alice", config.clone(), MockChatStore::default()).unwrap(); + let ctx1 = Context::open("alice", config.clone(), ChatStorage::in_memory()).unwrap(); let pubkey1 = ctx1._identity.public_key(); let name1 = ctx1.installation_name().to_string(); drop(ctx1); - let ctx2 = Context::open("alice", config, MockChatStore::default()).unwrap(); + let ctx2 = Context::open("alice", config, ChatStorage::in_memory()).unwrap(); let pubkey2 = ctx2._identity.public_key(); let name2 = ctx2.installation_name().to_string(); @@ -415,7 +311,7 @@ mod tests { let mut ctx2 = Context::open("alice", config.clone(), store2).unwrap(); let intro = Introduction::try_from(bundle1.as_slice()).unwrap(); - let mut bob = Context::new_with_name("bob", MockChatStore::default()); + let mut bob = Context::new_with_name("bob", ChatStorage::in_memory()); let (_, payloads) = bob.create_private_convo(&intro, b"hello after restart"); let payload = payloads.first().unwrap(); @@ -439,7 +335,7 @@ mod tests { let store = ChatStorage::new(config.clone()).unwrap(); let mut alice = Context::open("alice", config.clone(), store).unwrap(); - let mut bob = Context::new_with_name("bob", MockChatStore::default()); + let mut bob = Context::new_with_name("bob", ChatStorage::in_memory()); let bundle = alice.create_intro_bundle().unwrap(); let intro = Introduction::try_from(bundle.as_slice()).unwrap(); @@ -449,14 +345,14 @@ mod tests { let content = alice.handle_payload(&payload.data).unwrap().unwrap(); assert!(content.is_new_convo); - let convos = alice.storage.load_conversations().unwrap(); + let convos = alice.store.load_conversations().unwrap(); assert_eq!(convos.len(), 1); assert_eq!(convos[0].kind.as_str(), "private_v1"); drop(alice); let store2 = ChatStorage::new(config.clone()).unwrap(); let alice2 = Context::open("alice", config, store2).unwrap(); - let convos = alice2.storage.load_conversations().unwrap(); + let convos = alice2.store.load_conversations().unwrap(); assert_eq!(convos.len(), 1, "conversation metadata should persist"); } @@ -473,7 +369,7 @@ mod tests { // Alice and Bob establish a conversation let store = ChatStorage::new(config.clone()).unwrap(); let mut alice = Context::open("alice", config.clone(), store).unwrap(); - let mut bob = Context::new_with_name("bob", MockChatStore::default()); + let mut bob = Context::new_with_name("bob", ChatStorage::in_memory()); let bundle = alice.create_intro_bundle().unwrap(); let intro = Introduction::try_from(bundle.as_slice()).unwrap(); diff --git a/core/conversations/src/inbox/handler.rs b/core/conversations/src/inbox/handler.rs index d275cd9..b78f5ba 100644 --- a/core/conversations/src/inbox/handler.rs +++ b/core/conversations/src/inbox/handler.rs @@ -10,10 +10,10 @@ use crypto::{PrekeyBundle, SymmetricKey32}; use crate::context::Introduction; use crate::conversation::{ChatError, ConversationId, Convo, Id, PrivateV1Convo}; use crate::crypto::{CopyBytes, PrivateKey, PublicKey}; -use crypto::Identity; use crate::inbox::handshake::InboxHandshake; use crate::proto; use crate::types::{AddressedEncryptedPayload, ContentData}; +use crypto::Identity; /// Compute the deterministic Delivery_address for an installation fn delivery_address_for_installation(_: PublicKey) -> String { @@ -239,7 +239,7 @@ impl Id for Inbox { #[cfg(test)] mod tests { use super::*; - use chat_sqlite::ChatStorage; + use sqlite::ChatStorage; use storage::{EphemeralKeyStore, StorageConfig}; #[test] diff --git a/core/conversations/src/lib.rs b/core/conversations/src/lib.rs index 9254169..5f4fcfe 100644 --- a/core/conversations/src/lib.rs +++ b/core/conversations/src/lib.rs @@ -9,9 +9,9 @@ mod types; mod utils; pub use api::*; -pub use chat_sqlite::ChatStorage; pub use context::{Context, Introduction}; pub use errors::ChatError; +pub use sqlite::ChatStorage; pub use storage::StorageConfig; #[cfg(test)] diff --git a/core/chat-sqlite/Cargo.toml b/core/sqlite/Cargo.toml similarity index 93% rename from core/chat-sqlite/Cargo.toml rename to core/sqlite/Cargo.toml index e7740cd..7f7e5aa 100644 --- a/core/chat-sqlite/Cargo.toml +++ b/core/sqlite/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "chat-sqlite" +name = "sqlite" version = "0.1.0" edition = "2024" description = "SQLite storage implementation for libchat" diff --git a/core/chat-sqlite/src/lib.rs b/core/sqlite/src/lib.rs similarity index 98% rename from core/chat-sqlite/src/lib.rs rename to core/sqlite/src/lib.rs index 1433212..1ac89e6 100644 --- a/core/chat-sqlite/src/lib.rs +++ b/core/sqlite/src/lib.rs @@ -29,6 +29,10 @@ impl ChatStorage { Self::run_migrations(db) } + pub fn in_memory() -> Self { + Self::new(StorageConfig::InMemory).unwrap() + } + /// Applies all migrations and returns the storage instance. fn run_migrations(mut db: SqliteDb) -> Result { migrations::apply_migrations(db.connection_mut())?; @@ -111,10 +115,7 @@ impl EphemeralKeyStore for ChatStorage { } /// Loads a single ephemeral key by its public key hex. - fn load_ephemeral_key( - &self, - public_key_hex: &str, - ) -> Result, StorageError> { + fn load_ephemeral_key(&self, public_key_hex: &str) -> Result, StorageError> { let mut stmt = self .db .connection() diff --git a/core/chat-sqlite/src/migrations.rs b/core/sqlite/src/migrations.rs similarity index 100% rename from core/chat-sqlite/src/migrations.rs rename to core/sqlite/src/migrations.rs diff --git a/core/chat-sqlite/src/migrations/001_initial_schema.sql b/core/sqlite/src/migrations/001_initial_schema.sql similarity index 100% rename from core/chat-sqlite/src/migrations/001_initial_schema.sql rename to core/sqlite/src/migrations/001_initial_schema.sql diff --git a/core/chat-sqlite/src/types.rs b/core/sqlite/src/types.rs similarity index 100% rename from core/chat-sqlite/src/types.rs rename to core/sqlite/src/types.rs