Switch to a lighter sqlite dependency
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
parent
e909e04c6c
commit
b8c2ab5316
|
|
@ -2,17 +2,6 @@
|
|||
# It is not intended for manual editing.
|
||||
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"
|
||||
|
|
@ -306,18 +295,6 @@ dependencies = [
|
|||
"getrandom",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
|
@ -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"
|
||||
|
|
@ -555,17 +520,6 @@ dependencies = [
|
|||
"pkg-config",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
|
@ -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",
|
||||
]
|
||||
|
|
@ -948,20 +902,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
|
@ -1055,12 +995,6 @@ version = "0.3.10"
|
|||
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"
|
||||
|
|
@ -1071,6 +1005,36 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
)?;
|
||||
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(updated > 0)
|
||||
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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" }
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue