use std::path::PathBuf; use rusqlite::{params, Connection, Result}; use crate::files; use super::net::{*}; use super::files::{*}; /* Cache is the in-memory database Any changes/updates are written to file database */ struct Item{ title: String, content: Option } const DB_LOCATION: &str = "rsscar.db"; fn get_db_path() -> PathBuf{ get_data_directory().join(DB_LOCATION) } const feeds_table_create: &str = "CREATE TABLE IF NOT EXISTS 'feeds' ( 'feedID' INTEGER NOT NULL, 'title' TEXT NOT NULL, 'description' TEXT, 'icon' BLOB, 'url' text not null unique on conflict replace, 'subscribed' INTEGER, 'last_updated' TEXT , PRIMARY KEY('feedID') );"; const feeds_index_create: &str = "CREATE INDEX IF NOT EXISTS 'subscribed_feeds_idx' ON 'feeds' ( 'feedID' ASC ) WHERE 'subscribed' = 1;"; /* */ const items_table_create: &str = "CREATE TABLE IF NOT EXISTS 'items' ( 'itemID' INTEGER NOT NULL, 'title' TEXT NOT NULL, 'icon' BLOB, 'url' text not null unique on conflict replace, 'description' TEXT, 'content' TEXT, 'read' INTEGER DEFAULT 0, PRIMARY KEY('itemID') );"; const items_index_create: &str = "CREATE INDEX IF NOT EXISTS 'items_idx' on 'items'('itemID' ASC);"; pub fn initialize() { let conn = Connection::open(get_db_path()).unwrap(); conn.execute(feeds_table_create,[]).unwrap(); conn.execute(feeds_index_create,[]).unwrap(); conn.execute(items_table_create,[]).unwrap(); conn.execute(items_index_create,[]).unwrap(); conn.close(); println!("Database Initialized.") } pub fn add_feed(url: &str) { let conn = Connection::open(get_db_path()).unwrap(); let feed = load_rss(url).unwrap(); let new_feed = feed.clone(); conn.execute("insert into feeds(title,url,description) values(?1,?2,?3)", [feed.title,url.to_owned(),feed.description]).unwrap(); conn.close(); store_items(new_feed); } pub fn store_items(feed: rss::Channel) { let conn = Connection::open(get_db_path()).unwrap(); feed.items.iter().for_each(|i: &rss::Item|{ conn.execute("insert into items(url,title,description,content) values(?1,?2,?3,?4)",[ i.link.clone(), i.title.clone(), i.description.clone(), i.content.clone()] ).unwrap(); }); conn.close(); } pub fn return_item() -> String{ let conn = Connection::open(get_db_path()).unwrap(); let item = conn.query_row("select title,content from items where rowid=?1",[488],|row|{ Ok( Item { title: row.get(0).unwrap(), content: row.get(1).unwrap() } ) }).unwrap(); match item.content { Some(content) => content, None => panic!() } } struct ReturnedFeedURLs{ url: String } pub fn update_feeds() { //get feeds let conn = Connection::open(get_db_path()).unwrap(); let mut stmt = conn.prepare("select url from feeds").unwrap(); let rows = stmt.query_map([],|row| { Ok(ReturnedFeedURLs{ url:row.get(0).unwrap() }) }).unwrap(); let mut urls: Vec = Vec::new(); for feed in rows{ let url = feed.unwrap().url.clone(); urls.push(url); } stmt.finalize(); conn.close(); for u in urls { store_items(load_rss(&u).unwrap()); } //for each feed // insert items into database //close out }