Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Switch to a lighter sqlite dependency
Alexis Sellier committed 3 years ago
commit b8c2ab53163e184bd8e730c445b0930cb2a006c6
parent e909e04c6c22d37da5c39f86f873d607d372c024
5 files changed +91 -127
modified Cargo.lock
@@ -3,17 +3,6 @@
version = 3

[[package]]
-
name = "ahash"
-
version = "0.7.6"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
-
dependencies = [
-
 "getrandom",
-
 "once_cell",
-
 "version_check",
-
]
-

-
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -307,18 +296,6 @@ dependencies = [
]

[[package]]
-
name = "fallible-iterator"
-
version = "0.2.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
-

-
[[package]]
-
name = "fallible-streaming-iterator"
-
version = "0.1.9"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a"
-

-
[[package]]
name = "fastrand"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -419,18 +396,6 @@ name = "hashbrown"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
dependencies = [
-
 "ahash",
-
]
-

-
[[package]]
-
name = "hashlink"
-
version = "0.8.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
-
dependencies = [
-
 "hashbrown",
-
]

[[package]]
name = "hermit-abi"
@@ -556,17 +521,6 @@ dependencies = [
]

[[package]]
-
name = "libsqlite3-sys"
-
version = "0.25.1"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "9f0455f2c1bc9a7caa792907026e469c1d91761fb0ea37cbb16427c77280cf35"
-
dependencies = [
-
 "cc",
-
 "pkg-config",
-
 "vcpkg",
-
]
-

-
[[package]]
name = "libssh2-sys"
version = "0.2.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -837,11 +791,11 @@ dependencies = [
 "quickcheck_macros",
 "radicle-git-ext",
 "radicle-ssh",
-
 "rusqlite",
 "serde",
 "serde_json",
 "sha2 0.10.6",
 "siphasher",
+
 "sqlite",
 "tempfile",
 "thiserror",
 "zeroize",
@@ -881,9 +835,9 @@ dependencies = [
 "quickcheck",
 "quickcheck_macros",
 "radicle",
-
 "rusqlite",
 "serde",
 "serde_json",
+
 "sqlite",
 "tempfile",
 "thiserror",
]
@@ -949,20 +903,6 @@ dependencies = [
]

[[package]]
-
name = "rusqlite"
-
version = "0.28.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a"
-
dependencies = [
-
 "bitflags",
-
 "fallible-iterator",
-
 "fallible-streaming-iterator",
-
 "hashlink",
-
 "libsqlite3-sys",
-
 "smallvec",
-
]
-

-
[[package]]
name = "ryu"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1056,12 +996,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"

[[package]]
-
name = "smallvec"
-
version = "1.10.0"
-
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
-

-
[[package]]
name = "socket2"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1072,6 +1006,36 @@ dependencies = [
]

[[package]]
+
name = "sqlite"
+
version = "0.27.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e2df8edd55685048550daaaf2be9024182f3523086cc86f7d50c136e55173e8c"
+
dependencies = [
+
 "libc",
+
 "sqlite3-sys",
+
]
+

+
[[package]]
+
name = "sqlite3-src"
+
version = "0.4.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d1815a7a02c996eb8e5c64f61fcb6fd9b12e593ce265c512c5853b2513635691"
+
dependencies = [
+
 "cc",
+
 "pkg-config",
+
]
+

+
[[package]]
+
name = "sqlite3-sys"
+
version = "0.14.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "d47c99824fc55360ba00caf28de0b8a0458369b832e016a64c13af0ad9fbb9ee"
+
dependencies = [
+
 "libc",
+
 "sqlite3-src",
+
]
+

+
[[package]]
name = "syn"
version = "1.0.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
modified radicle-node/Cargo.toml
@@ -19,7 +19,7 @@ log = { version = "0.4.17", features = ["std"] }
nakamoto-net = { version = "0.3.0" }
nakamoto-net-poll = { version = "0.3.0" }
nonempty = { version = "0.8.0", features = ["serialize"] }
-
rusqlite = { version = "0.28.0", features = ["bundled"] }
+
sqlite = { version = "0.27.0" }
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }
tempfile = { version = "3.3.0" }
modified radicle-node/src/service/routing.rs
@@ -1,7 +1,8 @@
use std::collections::HashSet;
+
use std::fmt;
use std::path::Path;

-
use rusqlite as sql;
+
use sqlite as sql;
use thiserror::Error;

use crate::prelude::{Id, NodeId};
@@ -15,11 +16,16 @@ pub enum Error {
}

/// Persistent file storage for a routing table.
-
#[derive(Debug)]
pub struct Table {
    db: sql::Connection,
}

+
impl fmt::Debug for Table {
+
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+
        write!(f, "Table(..)")
+
    }
+
}
+

impl Table {
    const SCHEMA: &str = include_str!("routing/schema.sql");

@@ -27,15 +33,15 @@ impl Table {
    /// if an existing store isn't found.
    pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
        let db = sql::Connection::open(path)?;
-
        db.execute(Self::SCHEMA, [])?;
+
        db.execute(Self::SCHEMA)?;

        Ok(Self { db })
    }

    /// Create a new in-memory routing table.
    pub fn memory() -> Result<Self, Error> {
-
        let db = sql::Connection::open_in_memory()?;
-
        db.execute(Self::SCHEMA, [])?;
+
        let db = sql::Connection::open(":memory:")?;
+
        db.execute(Self::SCHEMA)?;

        Ok(Self { db })
    }
@@ -57,36 +63,42 @@ impl Store for Table {
    fn get(&self, id: &Id) -> Result<HashSet<NodeId>, Error> {
        let mut stmt = self
            .db
-
            .prepare("SELECT (node) FROM routing WHERE resource = ?")?;
-
        let mut rows = stmt.query([id])?;
+
            .prepare("SELECT (node) FROM routing WHERE resource = ?")?
+
            .bind(1, id)?
+
            .into_cursor();
        let mut nodes = HashSet::new();

-
        while let Ok(Some(row)) = rows.next() {
-
            let field = row.get(0)?;
-
            nodes.insert(field);
+
        while let Some(Ok(row)) = stmt.next() {
+
            nodes.insert(row.get::<NodeId, _>(0));
        }
        Ok(nodes)
    }

    fn insert(&mut self, id: Id, node: NodeId) -> Result<bool, Error> {
-
        let updated = self.db.execute(
-
            "INSERT INTO routing (resource, node, time) VALUES (?, ?, ?) ON CONFLICT DO NOTHING",
-
            (id, node, 0),
-
        )?;
-

-
        Ok(updated > 0)
+
        self.db
+
            .prepare(
+
                "INSERT INTO routing (resource, node, time)
+
                 VALUES (?, ?, ?)
+
                 ON CONFLICT DO NOTHING",
+
            )?
+
            .bind(1, &id)?
+
            .bind(2, &node)?
+
            .bind(3, 0)?
+
            .next()?;
+

+
        Ok(self.db.change_count() > 0)
    }

    fn entries(&self) -> Result<Box<dyn Iterator<Item = (Id, NodeId)>>, Error> {
        let mut stmt = self
            .db
-
            .prepare("SELECT resource, node FROM routing ORDER BY resource")?;
-
        let mut rows = stmt.query([])?;
+
            .prepare("SELECT resource, node FROM routing ORDER BY resource")?
+
            .into_cursor();
        let mut entries = Vec::new();

-
        while let Ok(Some(row)) = rows.next() {
-
            let id = row.get(0)?;
-
            let node = row.get(1)?;
+
        while let Some(Ok(row)) = stmt.next() {
+
            let id = row.get(0);
+
            let node = row.get(1);

            entries.push((id, node));
        }
@@ -94,12 +106,13 @@ impl Store for Table {
    }

    fn remove(&mut self, id: &Id, node: &NodeId) -> Result<bool, Error> {
-
        let deleted = self.db.execute(
-
            "DELETE FROM routing WHERE resource = ? AND node = ?",
-
            (id, node),
-
        )?;
+
        self.db
+
            .prepare("DELETE FROM routing WHERE resource = ? AND node = ?")?
+
            .bind(1, id)?
+
            .bind(2, node)?
+
            .next()?;

-
        Ok(deleted > 0)
+
        Ok(self.db.change_count() > 0)
    }
}

@@ -129,7 +142,7 @@ mod test {
    }

    #[test]
-
    fn test_iter() {
+
    fn test_entries() {
        let ids = arbitrary::set::<Id>(6..9);
        let nodes = arbitrary::set::<NodeId>(6..9);
        let mut db = Table::open(":memory:").unwrap();
@@ -160,13 +173,11 @@ mod test {
                db.insert(*id, *node).unwrap();
            }
        }
-

        for id in &ids {
            for node in &nodes {
                assert!(db.remove(id, node).unwrap());
            }
        }
-

        for id in &ids {
            assert!(db.get(id).unwrap().is_empty());
        }
modified radicle/Cargo.toml
@@ -8,7 +8,7 @@ edition = "2021"
[features]
default = []
test = ["quickcheck"]
-
sql = ["rusqlite"]
+
sql = ["sqlite"]

[dependencies]
base64 = { version= "0.13" }
@@ -28,7 +28,7 @@ serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["preserve_order"] }
siphasher = { version = "0.3.10" }
radicle-git-ext = { version = "0", features = ["serde"] }
-
rusqlite = { version = "0.28.0", features = ["bundled"], optional = true }
+
sqlite = { version = "0.27.0", optional = true }
nonempty = { version = "0.8.0", features = ["serialize"] }
tempfile = { version = "3.3.0" }
thiserror = { version = "1" }
modified radicle/src/sql.rs
@@ -1,48 +1,37 @@
-
use std::str;
use std::str::FromStr;

-
use rusqlite as sql;
-
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
+
use sqlite as sql;
+
use sqlite::Value;

use crate::crypto::PublicKey;
use crate::identity::Id;

-
impl FromSql for Id {
-
    fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
+
impl sql::ValueInto for Id {
+
    fn into(value: &Value) -> Option<Self> {
        match value {
-
            ValueRef::Text(id) => {
-
                let id = str::from_utf8(id).map_err(|e| FromSqlError::Other(Box::new(e)))?;
-
                let id = Id::from_str(id).map_err(|e| FromSqlError::Other(Box::new(e)))?;
-

-
                Ok(id)
-
            }
-
            _ => Err(FromSqlError::InvalidType),
+
            Value::String(id) => Id::from_str(id).ok(),
+
            _ => None,
        }
    }
}

-
impl ToSql for Id {
-
    fn to_sql(&self) -> sql::Result<ToSqlOutput<'_>> {
-
        Ok(ToSqlOutput::from(self.to_string()))
+
impl sqlite::Bindable for &Id {
+
    fn bind(self, stmt: &mut sql::Statement<'_>, i: usize) -> sql::Result<()> {
+
        self.to_human().as_str().bind(stmt, i)
    }
}

-
impl FromSql for PublicKey {
-
    fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
+
impl sql::ValueInto for PublicKey {
+
    fn into(value: &Value) -> Option<Self> {
        match value {
-
            ValueRef::Text(pk) => {
-
                let pk = str::from_utf8(pk).map_err(|e| FromSqlError::Other(Box::new(e)))?;
-
                let pk = PublicKey::from_str(pk).map_err(|e| FromSqlError::Other(Box::new(e)))?;
-

-
                Ok(pk)
-
            }
-
            _ => Err(FromSqlError::InvalidType),
+
            Value::String(id) => PublicKey::from_str(id).ok(),
+
            _ => None,
        }
    }
}

-
impl ToSql for PublicKey {
-
    fn to_sql(&self) -> sql::Result<ToSqlOutput<'_>> {
-
        Ok(ToSqlOutput::from(self.to_string()))
+
impl sqlite::Bindable for &PublicKey {
+
    fn bind(self, stmt: &mut sql::Statement<'_>, i: usize) -> sql::Result<()> {
+
        self.to_human().as_str().bind(stmt, i)
    }
}