1use std::ops::Deref;
2use std::str::FromStr;
3
4use sqlite as sql;
5use sqlite::Value;
6
7use crate::node;
8use crate::node::{Address, UserAgent};
9
10pub fn transaction<T, E: From<sql::Error>>(
13 db: &sql::Connection,
14 query: impl FnOnce(&sql::Connection) -> Result<T, E>,
15) -> Result<T, E> {
16 db.execute("BEGIN")?;
17
18 match query(db) {
19 Ok(result) => {
20 db.execute("COMMIT")?;
21 Ok(result)
22 }
23 Err(err) => {
24 db.execute("ROLLBACK")?;
25 Err(err)
26 }
27 }
28}
29
30impl sql::BindableWithIndex for node::Features {
31 fn bind<I: sql::ParameterIndex>(self, stmt: &mut sql::Statement<'_>, i: I) -> sql::Result<()> {
32 (*self.deref() as i64).bind(stmt, i)
33 }
34}
35
36impl TryFrom<&Value> for node::Features {
37 type Error = sql::Error;
38
39 fn try_from(value: &Value) -> Result<Self, Self::Error> {
40 match value {
41 Value::Integer(bits) => Ok(node::Features::from(*bits as u64)),
42 _ => Err(sql::Error {
43 code: None,
44 message: Some(format!(
45 "sql: invalid type `{:?}` for node features",
46 value.kind()
47 )),
48 }),
49 }
50 }
51}
52
53impl TryFrom<&sql::Value> for Address {
54 type Error = sql::Error;
55
56 fn try_from(value: &sql::Value) -> Result<Self, Self::Error> {
57 match value {
58 sql::Value::String(s) => Address::from_str(s.as_str()).map_err(|e| sql::Error {
59 code: None,
60 message: Some(e.to_string()),
61 }),
62 _ => Err(sql::Error {
63 code: None,
64 message: Some(format!(
65 "sql: invalid type `{:?}` for address",
66 value.kind()
67 )),
68 }),
69 }
70 }
71}
72
73impl sql::BindableWithIndex for &Address {
74 fn bind<I: sql::ParameterIndex>(self, stmt: &mut sql::Statement<'_>, i: I) -> sql::Result<()> {
75 self.to_string().bind(stmt, i)
76 }
77}
78
79impl TryFrom<&Value> for UserAgent {
80 type Error = sql::Error;
81
82 fn try_from(value: &Value) -> Result<Self, Self::Error> {
83 match value {
84 Value::String(ua) => UserAgent::from_str(ua).map_err(|e| sql::Error {
85 code: None,
86 message: Some(e.to_string()),
87 }),
88 _ => Err(sql::Error {
89 code: None,
90 message: Some(format!(
91 "sql: invalid type `{:?}` for user-agent",
92 value.kind()
93 )),
94 }),
95 }
96 }
97}