Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Use cascading deletes for removal of node rows
cloudhead committed 2 years ago
commit 0ae3c00cd718bd087a7d714a688e6588edb8bbdf
parent 3cad39a3a95c73c84b4e00dfdeb7b9220143eb39
2 files changed +11 -15
modified radicle/src/node/address/schema.sql
@@ -17,7 +17,7 @@ create table if not exists "nodes" (

create table if not exists "addresses" (
  -- Node ID.
-
  "node"               text      not null references "nodes" ("id"),
+
  "node"               text      not null references "nodes" ("id") on delete cascade,
  -- Address type.
  "type"               text      not null,
  -- Address value.
@@ -40,7 +40,7 @@ create table if not exists "addresses" (

create table if not exists "announcements" (
  -- Node ID.
-
  "node"               text      not null references "nodes" ("id"),
+
  "node"               text      not null references "nodes" ("id") on delete cascade,
  -- Repo ID, if any, for example in ref announcements.
  "repo"               text      not null,
  -- Announcement type.
@@ -66,7 +66,7 @@ create table if not exists "repo-sync-status" (
  -- Repository ID.
  "repo"                 text      not null,
  -- Node ID.
-
  "node"                 text      not null references "nodes" ("id"),
+
  "node"                 text      not null references "nodes" ("id") on delete cascade,
  -- Head of your `rad/sigrefs` branch that was synced.
  "head"                 text      not null,
  -- When this entry was last updated.
modified radicle/src/node/address/store.rs
@@ -47,6 +47,7 @@ impl From<sql::Connection> for Book {

impl Book {
    const SCHEMA: &str = include_str!("schema.sql");
+
    const PRAGMA: &str = "PRAGMA foreign_keys = ON";

    /// Open an address book at the given path. Creates a new address book if it
    /// doesn't exist.
@@ -58,6 +59,7 @@ impl Book {
                .with_read_write()
                .with_full_mutex(),
        )?;
+
        db.execute(Self::PRAGMA)?;
        db.execute(Self::SCHEMA)?;

        Ok(Self { db })
@@ -67,6 +69,7 @@ impl Book {
    /// open databases, as no locking is required.
    pub fn reader<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
        let db = sql::Connection::open_with_flags(path, sqlite::OpenFlags::new().with_read_only())?;
+
        db.execute(Self::PRAGMA)?;
        db.execute(Self::SCHEMA)?;

        Ok(Self { db })
@@ -75,6 +78,7 @@ impl Book {
    /// Create a new in-memory address book.
    pub fn memory() -> Result<Self, Error> {
        let db = sql::Connection::open(":memory:")?;
+
        db.execute(Self::PRAGMA)?;
        db.execute(Self::SCHEMA)?;

        Ok(Self { db })
@@ -196,20 +200,12 @@ impl Store for Book {
    }

    fn remove(&mut self, node: &NodeId) -> Result<bool, Error> {
-
        transaction(&self.db, move |db| {
-
            db.prepare("DELETE FROM nodes WHERE id = ?")?
-
                .into_iter()
-
                .bind(&[node][..])?
-
                .next();
+
        let mut stmt = self.db.prepare("DELETE FROM nodes WHERE id = ?1")?;

-
            db.prepare("DELETE FROM addresses WHERE node = ?")?
-
                .into_iter()
-
                .bind(&[node][..])?
-
                .next();
+
        stmt.bind((1, node))?;
+
        stmt.next()?;

-
            Ok(db.change_count() > 0)
-
        })
-
        .map_err(Error::from)
+
        Ok(self.db.change_count() > 0)
    }

    fn synced(