diff --git a/src/people.rs b/src/people.rs index ff136984..321dbf51 100644 --- a/src/people.rs +++ b/src/people.rs @@ -42,21 +42,43 @@ impl People { output } - pub async fn create_if_missing(&mut self, pubkeyhex: &PublicKeyHex) -> Result<(), Error> { - if self.people.contains_key(pubkeyhex) { + pub async fn create_all_if_missing(&mut self, pubkeys: &[PublicKeyHex]) -> Result<(), Error> { + // Collect the public keys that we don't have already (by checking in memory). + // Anything in memory surely already is on disk so we don't have to check disk. + let pubkeys: Vec<&PublicKeyHex> = pubkeys + .iter() + .filter(|pk| !self.people.contains_key(pk)) + .collect(); + + if pubkeys.is_empty() { return Ok(()); } - // Try loading from the database - let maybe_dbperson = Self::fetch_one(pubkeyhex).await?; + // Make sure all these people exist in the database + let mut sql: String = "INSERT OR IGNORE INTO person (pubkey) VALUES ".to_owned(); + sql.push_str(&"(?),".repeat(pubkeys.len())); + sql.pop(); // remove trailing comma - if let Some(dbperson) = maybe_dbperson { - // Insert into the map - self.people.insert(pubkeyhex.to_owned(), dbperson); - } else { - // Create new + let pubkey_strings: Vec = pubkeys.iter().map(|p| p.0.clone()).collect(); + + task::spawn_blocking(move || { + let maybe_db = GLOBALS.db.blocking_lock(); + let db = maybe_db.as_ref().unwrap(); + let mut stmt = db.prepare(&sql)?; + let mut pos = 1; + for pk in pubkey_strings.iter() { + stmt.raw_bind_parameter(pos, pk)?; + pos += 1; + } + stmt.raw_execute()?; + Ok::<(), Error>(()) + }) + .await??; + + // Make matching records for them in memory + for pk in pubkeys { let dbperson = DbPerson { - pubkey: pubkeyhex.to_owned(), + pubkey: pk.to_owned(), name: None, about: None, picture: None, @@ -67,10 +89,7 @@ impl People { followed: 0, followed_last_updated: 0, }; - // Insert into the map - self.people.insert(pubkeyhex.to_owned(), dbperson.clone()); - // Insert into the database - Self::insert(dbperson).await?; + self.people.insert(pk.to_owned(), dbperson); } Ok(()) @@ -83,7 +102,7 @@ impl People { asof: Unixtime, ) -> Result<(), Error> { // Sync in from database first - self.create_if_missing(pubkeyhex).await?; + self.create_all_if_missing(&[pubkeyhex.to_owned()]).await?; // Update the map let person = self.people.get_mut(pubkeyhex).unwrap(); @@ -524,6 +543,7 @@ impl People { } } + #[allow(dead_code)] async fn insert(person: DbPerson) -> Result<(), Error> { let sql = "INSERT OR IGNORE INTO person (pubkey, name, about, picture, dns_id, dns_id_valid, \ diff --git a/src/process.rs b/src/process.rs index e0c6f7d9..12989650 100644 --- a/src/process.rs +++ b/src/process.rs @@ -48,7 +48,7 @@ pub async fn process_new_event( .people .write() .await - .create_if_missing(&event.pubkey.into()) + .create_all_if_missing(&[event.pubkey.into()]) .await?; // Update person_relay.last_fetched