HomeServer/src/db.rs

98 lines
2.1 KiB
Rust
Raw Normal View History

2023-09-19 08:52:12 +00:00
use std::path::Path;
use anyhow::Result;
2023-09-19 09:18:22 +00:00
use rusqlite::{Connection, ToSql};
2023-09-19 08:52:12 +00:00
pub struct DataBase {
sql: Connection,
}
impl DataBase {
pub async fn new(path: impl AsRef<Path>) -> Result<Self> {
let me = Self {
sql: Connection::open(path)?,
};
me.generate_tables()?;
Ok(me)
}
fn generate_tables(&self) -> Result<()> {
2023-09-19 09:18:22 +00:00
self.sql.execute(
"CREATE TABLE IF NOT EXISTS data (
id INTEGER PRIMARY KEY,
device TEXT NOT NULL,
time BIGINT NOT NULL,
watts REAL NOT NULL
)",
[],
)?;
Ok(())
}
pub fn write(&self, device_name: &str, time: u64, watts: f32) -> Result<()> {
let params: &[&dyn ToSql] = &[&device_name, &time, &watts];
self.sql.execute(
"INSERT INTO data (device, time, watts)
VALUES (?1, ?2, ?3)",
params,
)?;
Ok(())
}
2023-09-20 10:19:41 +00:00
pub fn read(&self, device: &str) -> Result<Vec<(u64, f32)>> {
self.sql
.prepare(&format!(
// "
// SELECT time, watts
// FROM data
// WHERE device={device}
// "
"
SELECT time, watts
FROM data
"
))?
.query_map([], |row| Ok((row.get(0)?, row.get(1)?)))?
.map(|row| {
let (time, watts) = row?;
Ok((time, watts))
})
.collect()
}
2023-09-19 09:18:22 +00:00
}
#[cfg(test)]
mod test {
use std::fs;
use anyhow::Result;
use super::DataBase;
#[tokio::test]
async fn test_connection() -> Result<()> {
DataBase::new("connection_test.db").await?;
fs::remove_file("connection_test.db")?;
Ok(())
2023-09-19 08:52:12 +00:00
}
2023-09-19 09:18:22 +00:00
#[tokio::test]
async fn test_write() -> Result<()> {
let db = DataBase::new("write_test.db").await?;
db.write("test", 0, 5.5)?;
fs::remove_file("write_test.db")?;
Ok(())
2023-09-19 08:52:12 +00:00
}
}