mirror of
https://framagit.org/veretcle/scootaloo.git
synced 2025-07-21 17:34:37 +02:00
feature: state is held into a sqlite db
This commit is contained in:
133
src/state.rs
133
src/state.rs
@@ -2,32 +2,52 @@
|
||||
use crate::config::ScootalooConfig;
|
||||
|
||||
// std
|
||||
use std::{
|
||||
fs::{read_to_string, write},
|
||||
error::Error,
|
||||
};
|
||||
use std::error::Error;
|
||||
|
||||
// log
|
||||
use log::debug;
|
||||
|
||||
// rusqlite
|
||||
use rusqlite::{Connection, OpenFlags, params};
|
||||
use rusqlite::{Connection, params, OptionalExtension};
|
||||
|
||||
/// Reads last tweet id from a file
|
||||
pub fn read_state(s: &str) -> Option<u64> {
|
||||
let state = read_to_string(s);
|
||||
|
||||
if let Ok(s) = state {
|
||||
debug!("Last Tweet ID (from file): {}", &s);
|
||||
return s.parse::<u64>().ok();
|
||||
}
|
||||
|
||||
None
|
||||
/// Struct for each query line
|
||||
#[derive(Debug)]
|
||||
pub struct TweetToToot {
|
||||
pub tweet_id: u64,
|
||||
pub toot_id: String,
|
||||
}
|
||||
|
||||
/// Writes last treated tweet id to a file
|
||||
pub fn write_state(f: &str, s: u64) -> Result<(), std::io::Error> {
|
||||
write(f, format!("{}", s))
|
||||
/// if None is passed, read the last tweet from DB
|
||||
/// if a tweet_id is passed, read this particular tweet from DB
|
||||
pub fn read_state(conn: &Connection, s: Option<u64>) -> Result<Option<TweetToToot>, Box<dyn Error>> {
|
||||
debug!("Reading tweet_id {:?}", s);
|
||||
let query: String;
|
||||
match s {
|
||||
Some(i) => query = format!("SELECT * FROM tweet_to_toot WHERE tweet_id = {}", i),
|
||||
None => query = String::from("SELECT * FROM tweet_to_toot ORDER BY tweet_id DESC LIMIT 1"),
|
||||
};
|
||||
|
||||
let mut stmt = conn.prepare(&query)?;
|
||||
|
||||
let t = stmt.query_row([], |row| {
|
||||
Ok(TweetToToot {
|
||||
tweet_id: row.get(0)?,
|
||||
toot_id: row.get(1)?,
|
||||
})
|
||||
}).optional()?;
|
||||
|
||||
Ok(t)
|
||||
}
|
||||
|
||||
/// Writes last treated tweet id and toot id to the db
|
||||
pub fn write_state(conn: &Connection, t: TweetToToot) -> Result<(), Box<dyn Error>> {
|
||||
debug!("Write struct {:?}", t);
|
||||
conn.execute(
|
||||
"INSERT INTO tweet_to_toot (tweet_id, toot_id) VALUES (?1, ?2)",
|
||||
params![t.tweet_id, t.toot_id],
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/*********
|
||||
@@ -35,6 +55,7 @@ pub fn write_state(f: &str, s: u64) -> Result<(), std::io::Error> {
|
||||
*********/
|
||||
/// Initiates the DB from path
|
||||
pub fn init_db(config: &ScootalooConfig) -> Result<(), Box<dyn Error>> {
|
||||
debug!("Initializing DB for Scootaloo");
|
||||
let conn = Connection::open(&config.db_path)?;
|
||||
|
||||
conn.execute(
|
||||
@@ -57,7 +78,7 @@ mod tests {
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn test_init_db() {
|
||||
fn test_db() {
|
||||
let scootaloo_config = ScootalooConfig {
|
||||
db_path: String::from("/tmp/test_init_db.sqlite"),
|
||||
cache_path: String::from("/tmp/scootaloo"),
|
||||
@@ -69,33 +90,63 @@ mod tests {
|
||||
assert!(Path::new(&scootaloo_config.db_path).exists());
|
||||
|
||||
// open said file
|
||||
let conn = Connection::open_with_flags(&scootaloo_config.db_path, OpenFlags::SQLITE_OPEN_READ_ONLY).unwrap();
|
||||
|
||||
let conn = Connection::open(&scootaloo_config.db_path).unwrap();
|
||||
conn.execute(
|
||||
"SELECT * from tweet_to_toot;",
|
||||
[],
|
||||
).unwrap();
|
||||
|
||||
conn.close().unwrap();
|
||||
// write a state to DB
|
||||
let t = TweetToToot {
|
||||
tweet_id: 123456789,
|
||||
toot_id: String::from("987654321"),
|
||||
};
|
||||
write_state(&conn, t).unwrap();
|
||||
|
||||
let mut stmt = conn.prepare("SELECT * FROM tweet_to_toot limit 1;").unwrap();
|
||||
let mut rows = stmt.query([]).unwrap();
|
||||
|
||||
while let Some(row) = rows.next().unwrap() {
|
||||
assert_eq!(123456789 as u64, row.get::<_, u64>(0).unwrap());
|
||||
assert_eq!("987654321", row.get::<_, String>(1).unwrap());
|
||||
}
|
||||
|
||||
// write several other states
|
||||
let (t1, t2) = (
|
||||
TweetToToot {
|
||||
tweet_id: 11111111,
|
||||
toot_id: String::from("tamerelol"),
|
||||
},
|
||||
TweetToToot {
|
||||
tweet_id: 1123456789,
|
||||
toot_id: String::from("tonperemdr"),
|
||||
});
|
||||
|
||||
write_state(&conn, t1).unwrap();
|
||||
write_state(&conn, t2).unwrap();
|
||||
|
||||
match read_state(&conn, None).unwrap() {
|
||||
Some(i) => {
|
||||
assert_eq!(1123456789, i.tweet_id);
|
||||
assert_eq!("tonperemdr", &i.toot_id);
|
||||
},
|
||||
None => panic!("This should not happen!"),
|
||||
}
|
||||
|
||||
match read_state(&conn, Some(11111111)).unwrap() {
|
||||
Some(i) => {
|
||||
assert_eq!(11111111, i.tweet_id);
|
||||
assert_eq!("tamerelol", &i.toot_id);
|
||||
},
|
||||
None => panic!("This should not happen!"),
|
||||
}
|
||||
|
||||
match read_state(&conn, Some(0000000)).unwrap() {
|
||||
Some(_) => panic!("This should not happen"),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
remove_file(&scootaloo_config.db_path).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_read_state() {
|
||||
let scootaloo_config = ScootalooConfig {
|
||||
db_path: String::from("/tmp/test_read_state.sqlite"),
|
||||
cache_path: String::from("/tmp/scootaloo"),
|
||||
};
|
||||
|
||||
init_db(&scootaloo_config).unwrap();
|
||||
|
||||
let conn = Connection::open(&scootaloo_config.db_path).unwrap();
|
||||
|
||||
conn.execute(
|
||||
"INSERT INTO tweet_to_toot (tweet_id, toot_id) VALUES (?1, ?2)",
|
||||
params![123456789 as u64, String::from("987654321")],
|
||||
).unwrap();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user