use crate::database::models::{InsertTimeBoard, TimeBoard};
use crate::database::DbContext;
use failure::{format_err, Error};
use rusqlite::{ToSql, NO_PARAMS};
pub struct Timeboards<'a> {
db: &'a mut DbContext,
}
impl<'a> Timeboards<'a> {
#[inline]
pub fn new(db: &'a mut DbContext) -> Self {
Self { db }
}
#[inline]
pub fn run_migrations(&self) -> Result<(), Error> {
self.db.conn.execute(
"CREATE TABLE IF NOT EXISTS timeboards (
id TEXT NOT NULL PRIMARY KEY,
title TEXT NOT NULL,
description TEXT NOT NULL,
url TEXT NOT NULL,
modified DATETIME NOT NULL
);",
NO_PARAMS,
)?;
self.db.conn.execute(
"CREATE INDEX IF NOT EXISTS idx_timeboards_title_modified ON timeboards (title, modified);",
NO_PARAMS,
)?;
Ok(())
}
#[inline]
pub fn delete_all(&self) -> Result<(), Error> {
self.db.conn.execute("DELETE FROM timeboards;", NO_PARAMS)?;
Ok(())
}
#[inline]
pub fn insert(&mut self, timeboards: &[InsertTimeBoard]) -> Result<(), Error> {
let tx = self.db.conn.transaction()?;
let mut stmt = tx.prepare("INSERT INTO timeboards (id, title, description, url, modified) VALUES (?1, ?2, ?3, ?4, ?5)")?;
for board in timeboards {
let url = format!(
"https://{}.datadoghq.com/dash/{}",
self.db.subdomain, board.id
);
stmt.execute(&[
&board.id as &dyn ToSql,
&board.title,
&board.description.clone().unwrap_or_default(),
&url,
&board.modified,
])?;
}
stmt.finalize()?;
tx.commit()?;
Ok(())
}
#[inline]
pub fn find(&self, title: &str, limit: i64) -> Result<Vec<TimeBoard>, Error> {
let query = format!(
"%{}%",
title
.split_terminator(' ')
.flat_map(|s| s.split_terminator('_'))
.flat_map(|s| s.split_terminator('-'))
.collect::<Vec<&str>>()
.join("%")
);
let results = self.db.conn.prepare(
"SELECT id, title, description, url, modified FROM timeboards WHERE title LIKE ? ORDER BY modified DESC LIMIT ?",
)?.query_map(&[&query as &dyn ToSql,&limit], |row| {
Ok(TimeBoard {
id: row.get(0)?,
title:row.get(1)?,
description:row.get(2)?,
url:row.get(3)?,
modified:row.get(4)?,
})
})?.map(|r|{
match r{
Ok(v) => Ok(v),
Err(e)=> Err(format_err!("Query + Transform into Repository failed: {}",e)),
}
}).collect::<Result<Vec<_>, _>>();
results
}
}