Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Update `sqlite` dependency to 0.30.3
Alexis Sellier committed 3 years ago
commit db3568db2fd364f04c5cc4545c9a660765e80649
parent 207d2133f97241894a156d7913592d1dd91663bb
8 files changed +155 -107
modified Cargo.lock
@@ -2811,9 +2811,9 @@ dependencies = [

[[package]]
name = "sqlite"
-
version = "0.28.1"
+
version = "0.30.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-
checksum = "2d7dcfcc5c3247141692d47227842b3e9c3cf7fe8dd78d91786d76eb3f27b717"
+
checksum = "12e072cb5fb89b3fe5e9c9584676348feb503f9fb3ae829d9868171bc5372d48"
dependencies = [
 "libc",
 "sqlite3-sys",
modified radicle-crypto/Cargo.toml
@@ -18,7 +18,7 @@ cyphernet = { version = "0", optional = true }
multibase = { version = "0.9.1" }
serde = { version = "1", features = ["derive"] }
sha2 = { version = "0.10.2" }
-
sqlite = { version = "0.28.1", optional = true }
+
sqlite = { version = "0.30.3", optional = true }
thiserror = { version = "1" }
zeroize = { version = "1.5.7" }

modified radicle-crypto/src/lib.rs
@@ -351,27 +351,38 @@ impl<'a> From<&PublicKey> for git_ref_format::Component<'a> {
}

#[cfg(feature = "sqlite")]
-
impl sqlite::ValueInto for PublicKey {
-
    fn into(value: &sqlite::Value) -> Option<Self> {
-
        use sqlite::Value;
-
        match value {
-
            Value::String(id) => PublicKey::from_str(id).ok(),
-
            _ => None,
-
        }
+
impl From<&PublicKey> for sqlite::Value {
+
    fn from(pk: &PublicKey) -> Self {
+
        sqlite::Value::String(pk.to_human())
    }
}

#[cfg(feature = "sqlite")]
-
impl From<PublicKey> for sqlite::Value {
-
    fn from(pk: PublicKey) -> Self {
-
        sqlite::Value::String(pk.to_human())
+
impl TryFrom<&sqlite::Value> for PublicKey {
+
    type Error = sqlite::Error;
+

+
    fn try_from(value: &sqlite::Value) -> Result<Self, Self::Error> {
+
        match value {
+
            sqlite::Value::String(s) => Self::from_str(s).map_err(|e| sqlite::Error {
+
                code: None,
+
                message: Some(e.to_string()),
+
            }),
+
            _ => Err(sqlite::Error {
+
                code: None,
+
                message: None,
+
            }),
+
        }
    }
}

#[cfg(feature = "sqlite")]
-
impl sqlite::Bindable for &PublicKey {
-
    fn bind(self, stmt: &mut sqlite::Statement<'_>, i: usize) -> sqlite::Result<()> {
-
        sqlite::Value::from(*self).bind(stmt, i)
+
impl sqlite::BindableWithIndex for &PublicKey {
+
    fn bind<I: sqlite::ParameterIndex>(
+
        self,
+
        stmt: &mut sqlite::Statement<'_>,
+
        i: I,
+
    ) -> sqlite::Result<()> {
+
        sqlite::Value::from(self).bind(stmt, i)
    }
}

modified radicle-node/Cargo.toml
@@ -23,7 +23,7 @@ nakamoto-net = { version = "0.3.0" }
nakamoto-net-poll = { version = "0.3.0" }
nonempty = { version = "0.8.0", features = ["serialize"] }
qcheck = { version = "1", default-features = false, optional = true }
-
sqlite = { version = "0.28.1" }
+
sqlite = { version = "0.30.3" }
sqlite3-src = { version = "0.4.0", features = ["bundled"] } # Ensures static linking
scrypt = { version = "0.10.0", default-features = false }
serde = { version = "1", features = ["derive"] }
modified radicle-node/src/address/store.rs
@@ -62,24 +62,24 @@ impl Store for Book {
            .db
            .prepare("SELECT features, alias, timestamp FROM nodes WHERE id = ?")?;

-
        stmt.bind(1, node)?;
+
        stmt.bind((1, node))?;

-
        if let Some(Ok(row)) = stmt.into_cursor().next() {
-
            let features = row.get::<node::Features, _>("features");
-
            let alias = row.get::<String, _>("alias");
-
            let timestamp = row.get::<i64, _>("timestamp") as Timestamp;
+
        if let Some(Ok(row)) = stmt.into_iter().next() {
+
            let features = row.read::<node::Features, _>("features");
+
            let alias = row.read::<&str, _>("alias").to_owned();
+
            let timestamp = row.read::<i64, _>("timestamp") as Timestamp;
            let mut addrs = Vec::new();

            let mut stmt = self
                .db
                .prepare("SELECT type, value, source FROM addresses WHERE node = ?")?;
-
            stmt.bind(1, node)?;
+
            stmt.bind((1, node))?;

-
            for row in stmt.into_cursor() {
+
            for row in stmt.into_iter() {
                let row = row?;
-
                let _typ = row.get::<AddressType, _>("type");
-
                let addr = row.get::<Address, _>("value");
-
                let source = row.get::<Source, _>("source");
+
                let _typ = row.read::<AddressType, _>("type");
+
                let addr = row.read::<Address, _>("value");
+
                let source = row.read::<Source, _>("source");

                addrs.push(KnownAddress {
                    addr,
@@ -104,11 +104,11 @@ impl Store for Book {
        let row = self
            .db
            .prepare("SELECT COUNT(*) FROM addresses")?
-
            .into_cursor()
+
            .into_iter()
            .next()
            .unwrap()
            .unwrap();
-
        let count = row.get::<i64, _>(0) as usize;
+
        let count = row.read::<i64, _>(0) as usize;

        Ok(count)
    }
@@ -130,10 +130,10 @@ impl Store for Book {
                 WHERE timestamp < ?4",
            )?;

-
            stmt.bind(1, node)?;
-
            stmt.bind(2, features)?;
-
            stmt.bind(3, alias)?;
-
            stmt.bind(4, timestamp as i64)?;
+
            stmt.bind((1, node))?;
+
            stmt.bind((2, features))?;
+
            stmt.bind((3, alias))?;
+
            stmt.bind((4, timestamp as i64))?;
            stmt.next()?;

            for addr in addrs {
@@ -144,11 +144,11 @@ impl Store for Book {
                     SET timestamp = ?5
                     WHERE timestamp < ?5",
                )?;
-
                stmt.bind(1, node)?;
-
                stmt.bind(2, AddressType::from(&addr.addr))?;
-
                stmt.bind(3, addr.addr)?;
-
                stmt.bind(4, addr.source)?;
-
                stmt.bind(5, timestamp as i64)?;
+
                stmt.bind((1, node))?;
+
                stmt.bind((2, AddressType::from(&addr.addr)))?;
+
                stmt.bind((3, addr.addr))?;
+
                stmt.bind((4, addr.source))?;
+
                stmt.bind((5, timestamp as i64))?;
                stmt.next()?;
            }
            Ok(db.change_count() > 0)
@@ -159,13 +159,13 @@ 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_cursor()
-
                .bind(&[(*node).into()])?
+
                .into_iter()
+
                .bind(&[node][..])?
                .next();

            db.prepare("DELETE FROM addresses WHERE node = ?")?
-
                .into_cursor()
-
                .bind(&[(*node).into()])?
+
                .into_iter()
+
                .bind(&[node][..])?
                .next();

            Ok(db.change_count() > 0)
@@ -177,14 +177,14 @@ impl Store for Book {
        let mut stmt = self
            .db
            .prepare("SELECT node, type, value, source FROM addresses ORDER BY node")?
-
            .into_cursor();
+
            .into_iter();
        let mut entries = Vec::new();

        while let Some(Ok(row)) = stmt.next() {
-
            let node = row.get("node");
-
            let _typ = row.get::<AddressType, _>("type");
-
            let addr = row.get::<Address, _>("value");
-
            let source = row.get::<Source, _>("source");
+
            let node = row.read::<NodeId, _>("node");
+
            let _typ = row.read::<AddressType, _>("type");
+
            let addr = row.read::<Address, _>("value");
+
            let source = row.read::<Source, _>("source");

            entries.push((
                node,
@@ -229,37 +229,53 @@ pub trait Store {
    fn entries(&self) -> Result<Box<dyn Iterator<Item = (NodeId, KnownAddress)>>, Error>;
}

-
impl sql::ValueInto for Address {
-
    fn into(value: &sql::Value) -> Option<Self> {
+
impl TryFrom<&sql::Value> for Address {
+
    type Error = sql::Error;
+

+
    fn try_from(value: &sql::Value) -> Result<Self, Self::Error> {
        match value {
-
            sql::Value::String(s) => Address::from_str(s.as_str()).ok(),
-
            _ => None,
+
            sql::Value::String(s) => Address::from_str(s.as_str()).map_err(|_| sql::Error {
+
                code: None,
+
                message: None,
+
            }),
+
            _ => Err(sql::Error {
+
                code: None,
+
                message: None,
+
            }),
        }
    }
}

-
impl sql::Bindable for Address {
-
    fn bind(self, stmt: &mut sql::Statement<'_>, i: usize) -> sql::Result<()> {
+
impl sql::BindableWithIndex for Address {
+
    fn bind<I: sql::ParameterIndex>(self, stmt: &mut sql::Statement<'_>, i: I) -> sql::Result<()> {
        self.to_string().bind(stmt, i)
    }
}

-
impl sql::ValueInto for Source {
-
    fn into(value: &sql::Value) -> Option<Self> {
+
impl TryFrom<&sql::Value> for Source {
+
    type Error = sql::Error;
+

+
    fn try_from(value: &sql::Value) -> Result<Self, Self::Error> {
        match value {
            sql::Value::String(s) => match s.as_str() {
-
                "dns" => Some(Source::Dns),
-
                "peer" => Some(Source::Peer),
-
                "imported" => Some(Source::Imported),
-
                _ => None,
+
                "dns" => Ok(Source::Dns),
+
                "peer" => Ok(Source::Peer),
+
                "imported" => Ok(Source::Imported),
+
                _ => Err(sql::Error {
+
                    code: None,
+
                    message: None,
+
                }),
            },
-
            _ => None,
+
            _ => Err(sql::Error {
+
                code: None,
+
                message: None,
+
            }),
        }
    }
}

-
impl sql::Bindable for Source {
-
    fn bind(self, stmt: &mut sql::Statement<'_>, i: usize) -> sql::Result<()> {
+
impl sql::BindableWithIndex for Source {
+
    fn bind<I: sql::ParameterIndex>(self, stmt: &mut sql::Statement<'_>, i: I) -> sql::Result<()> {
        match self {
            Self::Dns => "dns".bind(stmt, i),
            Self::Peer => "peer".bind(stmt, i),
@@ -268,23 +284,31 @@ impl sql::Bindable for Source {
    }
}

-
impl sql::ValueInto for AddressType {
-
    fn into(value: &sql::Value) -> Option<Self> {
+
impl TryFrom<&sql::Value> for AddressType {
+
    type Error = sql::Error;
+

+
    fn try_from(value: &sql::Value) -> Result<Self, Self::Error> {
        match value {
            sql::Value::String(s) => match s.as_str() {
-
                "ipv4" => Some(AddressType::Ipv4),
-
                "ipv6" => Some(AddressType::Ipv6),
-
                "hostname" => Some(AddressType::Hostname),
-
                "onion" => Some(AddressType::Onion),
-
                _ => None,
+
                "ipv4" => Ok(AddressType::Ipv4),
+
                "ipv6" => Ok(AddressType::Ipv6),
+
                "hostname" => Ok(AddressType::Hostname),
+
                "onion" => Ok(AddressType::Onion),
+
                _ => Err(sql::Error {
+
                    code: None,
+
                    message: None,
+
                }),
            },
-
            _ => None,
+
            _ => Err(sql::Error {
+
                code: None,
+
                message: None,
+
            }),
        }
    }
}

-
impl sql::Bindable for AddressType {
-
    fn bind(self, stmt: &mut sql::Statement<'_>, i: usize) -> sql::Result<()> {
+
impl sql::BindableWithIndex for AddressType {
+
    fn bind<I: sql::ParameterIndex>(self, stmt: &mut sql::Statement<'_>, i: I) -> sql::Result<()> {
        match self {
            Self::Ipv4 => "ipv4".bind(stmt, i),
            Self::Ipv6 => "ipv6".bind(stmt, i),
modified radicle-node/src/service/routing.rs
@@ -82,11 +82,11 @@ impl Store for Table {
        let mut stmt = self
            .db
            .prepare("SELECT (node) FROM routing WHERE resource = ?")?;
-
        stmt.bind(1, id)?;
+
        stmt.bind((1, id))?;

        let mut nodes = HashSet::new();
-
        for row in stmt.into_cursor() {
-
            nodes.insert(row?.get::<NodeId, _>("node"));
+
        for row in stmt.into_iter() {
+
            nodes.insert(row?.read::<NodeId, _>("node"));
        }
        Ok(nodes)
    }
@@ -95,11 +95,11 @@ impl Store for Table {
        let mut stmt = self
            .db
            .prepare("SELECT resource FROM routing WHERE node = ?")?;
-
        stmt.bind(1, node)?;
+
        stmt.bind((1, node))?;

        let mut resources = HashSet::new();
-
        for row in stmt.into_cursor() {
-
            resources.insert(row?.get::<Id, _>("resource"));
+
        for row in stmt.into_iter() {
+
            resources.insert(row?.read::<Id, _>("resource"));
        }
        Ok(resources)
    }
@@ -109,11 +109,11 @@ impl Store for Table {
            .db
            .prepare("SELECT (time) FROM routing WHERE resource = ? AND node = ?")?;

-
        stmt.bind(1, id)?;
-
        stmt.bind(2, node)?;
+
        stmt.bind((1, id))?;
+
        stmt.bind((2, node))?;

-
        if let Some(Ok(row)) = stmt.into_cursor().next() {
-
            return Ok(Some(row.get::<i64, _>("time") as Timestamp));
+
        if let Some(Ok(row)) = stmt.into_iter().next() {
+
            return Ok(Some(row.read::<i64, _>("time") as Timestamp));
        }
        Ok(None)
    }
@@ -128,9 +128,9 @@ impl Store for Table {
             WHERE time < ?3",
        )?;

-
        stmt.bind(1, &id)?;
-
        stmt.bind(2, &node)?;
-
        stmt.bind(3, time)?;
+
        stmt.bind((1, &id))?;
+
        stmt.bind((2, &node))?;
+
        stmt.bind((3, time))?;
        stmt.next()?;

        Ok(self.db.change_count() > 0)
@@ -140,12 +140,12 @@ impl Store for Table {
        let mut stmt = self
            .db
            .prepare("SELECT resource, node FROM routing ORDER BY resource")?
-
            .into_cursor();
+
            .into_iter();
        let mut entries = Vec::new();

        while let Some(Ok(row)) = stmt.next() {
-
            let id = row.get("resource");
-
            let node = row.get("node");
+
            let id = row.read("resource");
+
            let node = row.read("node");

            entries.push((id, node));
        }
@@ -157,8 +157,8 @@ impl Store for Table {
            .db
            .prepare("DELETE FROM routing WHERE resource = ? AND node = ?")?;

-
        stmt.bind(1, id)?;
-
        stmt.bind(2, node)?;
+
        stmt.bind((1, id))?;
+
        stmt.bind((2, node))?;
        stmt.next()?;

        Ok(self.db.change_count() > 0)
@@ -167,10 +167,10 @@ impl Store for Table {
    fn len(&self) -> Result<usize, Error> {
        let stmt = self.db.prepare("SELECT COUNT(1) FROM routing")?;
        let count: i64 = stmt
-
            .into_cursor()
+
            .into_iter()
            .next()
            .expect("COUNT will always return a single row")?
-
            .get(0);
+
            .read(0);
        let count: usize = count.try_into().map_err(|_| Error::UnitOverflow)?;
        Ok(count)
    }
@@ -186,8 +186,8 @@ impl Store for Table {
            "DELETE FROM routing WHERE rowid IN
            (SELECT rowid FROM routing WHERE time < ? LIMIT ?)",
        )?;
-
        stmt.bind(1, oldest)?;
-
        stmt.bind(2, limit)?;
+
        stmt.bind((1, oldest))?;
+
        stmt.bind((2, limit))?;
        stmt.next()?;

        Ok(self.db.change_count())
modified radicle/Cargo.toml
@@ -27,7 +27,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"] }
-
sqlite = { version = "0.28.1", optional = true }
+
sqlite = { version = "0.30.3", optional = true }
nonempty = { version = "0.8.0", features = ["serialize"] }
tempfile = { version = "3.3.0" }
thiserror = { version = "1" }
modified radicle/src/sql.rs
@@ -7,32 +7,45 @@ use sqlite::Value;
use crate::identity::Id;
use crate::node;

-
impl sql::ValueInto for Id {
-
    fn into(value: &Value) -> Option<Self> {
+
impl TryFrom<&Value> for Id {
+
    type Error = sql::Error;
+

+
    fn try_from(value: &Value) -> Result<Self, Self::Error> {
        match value {
-
            Value::String(id) => Id::from_str(id).ok(),
-
            _ => None,
+
            Value::String(id) => Id::from_str(id).map_err(|e| sql::Error {
+
                code: None,
+
                message: Some(e.to_string()),
+
            }),
+
            _ => Err(sql::Error {
+
                code: None,
+
                message: None,
+
            }),
        }
    }
}

-
impl sqlite::Bindable for &Id {
-
    fn bind(self, stmt: &mut sql::Statement<'_>, i: usize) -> sql::Result<()> {
+
impl sqlite::BindableWithIndex for &Id {
+
    fn bind<I: sql::ParameterIndex>(self, stmt: &mut sql::Statement<'_>, i: I) -> sql::Result<()> {
        self.to_human().as_str().bind(stmt, i)
    }
}

-
impl sql::Bindable for node::Features {
-
    fn bind(self, stmt: &mut sql::Statement<'_>, i: usize) -> sql::Result<()> {
+
impl sql::BindableWithIndex for node::Features {
+
    fn bind<I: sql::ParameterIndex>(self, stmt: &mut sql::Statement<'_>, i: I) -> sql::Result<()> {
        (*self.deref() as i64).bind(stmt, i)
    }
}

-
impl sql::ValueInto for node::Features {
-
    fn into(value: &Value) -> Option<Self> {
+
impl TryFrom<&Value> for node::Features {
+
    type Error = sql::Error;
+

+
    fn try_from(value: &Value) -> Result<Self, Self::Error> {
        match value {
-
            Value::Integer(bits) => Some(node::Features::from(*bits as u64)),
-
            _ => None,
+
            Value::Integer(bits) => Ok(node::Features::from(*bits as u64)),
+
            _ => Err(sql::Error {
+
                code: None,
+
                message: None,
+
            }),
        }
    }
}