diff --git a/migrations/01_init.sql b/migrations/01_init.sql index c0c4a40..bffce00 100644 --- a/migrations/01_init.sql +++ b/migrations/01_init.sql @@ -1,14 +1,14 @@ PRAGMA foreign_keys = ON; -CREATE TABLE IF NOT EXISTS global_actions ( +CREATE TABLE IF NOT EXISTS global_action ( name TEXT NOT NULL PRIMARY KEY, - last_finished INTEGER DEFAULT 0 NOT NULL + next_run INTEGER DEFAULT 0 NOT NULL ); -CREATE TABLE IF NOT EXISTS local_actions ( +CREATE TABLE IF NOT EXISTS local_action ( jail_name TEXT NOT NULL, tree TEXT NOT NULL, set_name TEXT NOT NULL, - last_finished INTEGER DEFAULT 0 NOT NULL, + next_run INTEGER DEFAULT 0 NOT NULL, PRIMARY KEY (jail_name, tree, set_name) ); diff --git a/src/db/init.rs b/src/db/init.rs index da78096..5455a79 100644 --- a/src/db/init.rs +++ b/src/db/init.rs @@ -1,19 +1,76 @@ use std::path::Path; +use std::time::Duration; +use std::time::SystemTime; +use rusqlite::params; use rusqlite::Connection; +use super::DbGlobalAction; +use super::DbLocalAction; + static DB_INIT_QUERY: &str = include_str!("../../migrations/01_init.sql"); -pub struct DbHandle { +pub(crate) struct DbHandle { conn: Connection, } impl DbHandle { - pub fn new>(db_path: P) -> Result> { - let mut conn: Connection = Connection::open(db_path).unwrap(); + pub(crate) fn new>(db_path: P) -> Result> { + let mut conn: Connection = Connection::open(db_path)?; let tx = conn.transaction()?; - tx.execute_batch(DB_INIT_QUERY).unwrap(); - tx.commit().unwrap(); + tx.execute_batch(DB_INIT_QUERY)?; + tx.commit()?; Ok(DbHandle { conn }) } + + pub(crate) fn get_pending_global_actions( + &mut self, + ) -> Result, Box> { + let now = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH)? + .as_secs(); + let mut stmt = self + .conn + .prepare("SELECT name, next_run FROM global_action WHERE next_run <= $1")?; + let rows = stmt + .query_map(params![now], |row| { + Ok(DbGlobalAction { + name: row.get(0)?, + next_run: row.get(1)?, + }) + })? + .collect::, _>>()?; + Ok(rows) + } + + pub(crate) fn get_pending_local_actions( + &mut self, + ) -> Result, Box> { + let now = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH)? + .as_secs(); + let mut stmt = self.conn.prepare( + "SELECT jail_name, tree, set_name, next_run FROM local_action WHERE next_run <= $1", + )?; + let rows = stmt + .query_map(params![now], |row| { + Ok(DbLocalAction { + jail_name: row.get(0)?, + tree: row.get(1)?, + set_name: row.get(2)?, + next_run: row.get(3)?, + }) + })? + .collect::, _>>()?; + Ok(rows) + } + + pub(crate) fn get_time_until_next_action( + &mut self, + ) -> Result> { + let now = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH)? + .as_secs(); + todo!() + } } diff --git a/src/db/mod.rs b/src/db/mod.rs index 1d2b5aa..4f8be4f 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,3 +1,6 @@ mod init; +mod types; pub(crate) use init::DbHandle; +pub(crate) use types::DbGlobalAction; +pub(crate) use types::DbLocalAction; diff --git a/src/db/types.rs b/src/db/types.rs new file mode 100644 index 0000000..1454aed --- /dev/null +++ b/src/db/types.rs @@ -0,0 +1,11 @@ +pub(crate) struct DbGlobalAction { + pub(crate) name: String, + pub(crate) next_run: i64, +} + +pub(crate) struct DbLocalAction { + pub(crate) jail_name: String, + pub(crate) tree: String, + pub(crate) set_name: String, + pub(crate) next_run: i64, +} diff --git a/src/main.rs b/src/main.rs index 0082382..eeac413 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +use std::{thread, time}; + mod db; fn main() -> Result<(), Box> { @@ -5,6 +7,8 @@ fn main() -> Result<(), Box> { .nth(1) .ok_or("Pass path to sqlite DB in first parameter.")?; let mut db_conn: db::DbHandle = db::DbHandle::new(db_path)?; - println!("Done."); - Ok(()) + + loop { + thread::sleep(time::Duration::from_secs(300)); + } }