Update `sqlite` dependency to 0.30.3

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
Alexis Sellier 2022-12-06 14:43:36 +01:00
parent 207d2133f9
commit db3568db2f
No known key found for this signature in database
8 changed files with 158 additions and 110 deletions

4
Cargo.lock generated
View File

@ -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",

View File

@ -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" }

View File

@ -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,
}
}
}
#[cfg(feature = "sqlite")]
impl From<PublicKey> for sqlite::Value {
fn from(pk: PublicKey) -> Self {
impl From<&PublicKey> for sqlite::Value {
fn from(pk: &PublicKey) -> Self {
sqlite::Value::String(pk.to_human())
}
}
#[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 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::BindableWithIndex for &PublicKey {
fn bind<I: sqlite::ParameterIndex>(
self,
stmt: &mut sqlite::Statement<'_>,
i: I,
) -> sqlite::Result<()> {
sqlite::Value::from(self).bind(stmt, i)
}
}

View File

@ -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"] }

View File

@ -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),

View File

@ -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())

View File

@ -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" }

View File

@ -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,
}),
}
}
}