extern crate dirs;
extern crate rusqlite;
extern crate serde_json;
extern crate time;
use cmd;
use cmd::{
create, delete, filter, filter_by_tag, filter_count, insert, search, search_by_day,
search_by_tag, search_count, select, select_by_day, select_by_tag, select_count,
sync_via_attach,
};
use rusqlite::Connection;
use std::fs;
use std::path::Path;
use Cmd;
use CmdDelete;
use CmdFilter;
use CmdInsert;
use CmdSearch;
use CmdSelect;
use CmdSyncViaAttach;
use Note;
pub fn get_sqlite_connection() -> Connection {
let p = sqlite3_db_location();
let path = Path::new(&p);
let conn = Connection::open(path).unwrap();
conn
}
fn sqlite3_db_location() -> String {
if cfg!(target_os = "android") {
fs::create_dir_all("/sdcard/LocalNative").unwrap();
return "/sdcard/LocalNative/localnative.sqlite3".to_string();
}
let mut dir_name = "LocalNative";
if cfg!(target_os = "ios") {
dir_name = "Documents";
}
let dir = format!(
"{}/{}",
dirs::home_dir().unwrap().to_str().unwrap(),
dir_name
);
eprintln!("db dir location: {}", dir);
fs::create_dir_all(&dir).unwrap();
format!("{}/localnative.sqlite3", dir)
}
pub fn run(text: &str) -> String {
if let Ok(cmd) = serde_json::from_str::<Cmd>(text) {
process(cmd, text)
} else {
r#"{"error": "cmd json error"}"#.to_string()
}
}
fn process(cmd: Cmd, text: &str) -> String {
eprintln!("process cmd {:?}", cmd);
let conn = get_sqlite_connection();
create(&conn);
match cmd.action.as_ref() {
"sync-via-attach" => {
if let Ok(s) = serde_json::from_str::<CmdSyncViaAttach>(text) {
sync_via_attach(&conn, &s.uri)
} else {
r#"{"error":"cmd sync-via-attach error"}"#.to_string()
}
}
"insert-image" => {
if let Ok(i) = serde_json::from_str::<CmdInsert>(text) {
let created_at =
time::strftime("%Y-%m-%d %H:%M:%S:%f UTC", &time::now_utc()).unwrap();
let note = Note {
rowid: 0i64,
title: i.title,
url: i.url,
tags: i.tags,
description: i.description,
comments: i.comments,
annotations: i.annotations,
created_at,
is_public: i.is_public,
};
cmd::image::insert_image(note);
if i.is_public {
eprintln!("is_public")
}
do_select(&conn, &i.limit, &i.offset)
} else {
r#"{"error":"cmd insert json error"}"#.to_string()
}
}
"insert" => {
if let Ok(i) = serde_json::from_str::<CmdInsert>(text) {
let created_at =
time::strftime("%Y-%m-%d %H:%M:%S:%f UTC", &time::now_utc()).unwrap();
let note = Note {
rowid: 0i64,
title: i.title,
url: i.url,
tags: i.tags,
description: i.description,
comments: i.comments,
annotations: i.annotations,
created_at,
is_public: i.is_public,
};
insert(note);
if i.is_public {
eprintln!("is_public")
}
do_select(&conn, &i.limit, &i.offset)
} else {
r#"{"error":"cmd insert json error"}"#.to_string()
}
}
"delete" => {
if let Ok(s) = serde_json::from_str::<CmdDelete>(text) {
delete(&conn, s.rowid);
do_search(&conn, &s.query, &s.limit, &s.offset)
} else {
r#"{"error":"cmd delete json error"}"#.to_string()
}
}
"select" => {
if let Ok(s) = serde_json::from_str::<CmdSelect>(text) {
do_select(&conn, &s.limit, &s.offset)
} else {
r#"{"error":"cmd select json error"}"#.to_string()
}
}
"search" => {
if let Ok(s) = serde_json::from_str::<CmdSearch>(text) {
do_search(&conn, &s.query, &s.limit, &s.offset)
} else {
r#"{"error":"cmd search json error"}"#.to_string()
}
}
"filter" => {
if let Ok(s) = serde_json::from_str::<CmdFilter>(text) {
do_filter(&conn, &s.query, &s.limit, &s.offset, &s.from, &s.to)
} else {
r#"{"error":"cmd filter json error"}"#.to_string()
}
}
_ => r#"{"error": "cmd no match"}"#.to_string(),
}
}
fn do_search(conn: &Connection, query: &str, limit: &u32, offset: &u32) -> String {
let c = search_count(&conn, query);
let j = search(&conn, query, limit, offset);
let d = search_by_day(&conn, query);
let t = search_by_tag(&conn, query);
let msg = format!(
r#"{{"count": {}, "notes":{}, "days": {}, "tags": {} }}"#,
c, j, d, t
);
msg
}
fn do_select(conn: &Connection, limit: &u32, offset: &u32) -> String {
let c = select_count(&conn);
let j = select(&conn, limit, offset);
let d = select_by_day(&conn);
let t = select_by_tag(&conn);
let msg = format!(
r#"{{"count": {}, "notes":{}, "days": {}, "tags": {} }}"#,
c, j, d, t
);
msg
}
fn do_filter(
conn: &Connection,
query: &str,
limit: &u32,
offset: &u32,
from: &str,
to: &str,
) -> String {
let c = filter_count(&conn, query, from, to);
let j = filter(&conn, query, from, to, limit, offset);
let t = filter_by_tag(&conn, query, from, to);
let msg = format!(r#"{{"count": {}, "notes":{}, "tags": {} }}"#, c, j, t);
msg
}