extern crate sqlite3;
use std::default::Default;
use std::env;
use std::io::Write;
use sqlite3::{
Access,
DatabaseConnection,
QueryFold,
ResultRowAccess,
SqliteResult,
StatementUpdate,
};
use sqlite3::access;
use sqlite3::access::flags::OPEN_READONLY;
pub fn main() {
let args : Vec<String> = env::args().collect();
let usage = "args: [-r] filename";
let cli_access = {
let ok = |flags, dbfile| Some(access::ByFilename { flags: flags, filename: dbfile });
let arg = |n| {
if args.len() > n { Some(args[n].as_ref()) }
else { None }
};
match (arg(1), arg(2)) {
(Some("-r"), Some(dbfile))
=> ok(OPEN_READONLY, dbfile),
(Some(dbfile), None)
=> ok(Default::default(), dbfile),
(_, _)
=> None
}
};
fn use_access<A: Access>(access: A) -> SqliteResult<Vec<Person>> {
let mut conn = try!(DatabaseConnection::new(access));
make_people(&mut conn)
}
fn lose(why: &str) {
let stderr = std::io::stderr();
let mut stderr_lock = stderr.lock();
stderr_lock.write_fmt(format_args!("{}", why)).unwrap()
}
match cli_access {
Some(a) => match use_access(a) {
Ok(x) => println!("Ok: {:?}", x),
Err(oops) => lose(format!("oops!: {:?}", oops).as_ref())
},
None => lose(usage)
}
}
#[derive(Debug, Clone)]
struct Person {
id: i32,
name: String,
}
fn make_people(conn: &mut DatabaseConnection) -> SqliteResult<Vec<Person>> {
try!(conn.exec("CREATE TABLE person (
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL
)"));
{
let mut tx = try!(conn.prepare("INSERT INTO person (id, name)
VALUES (0, 'Dan')"));
let changes = try!(tx.update(&[]));
assert_eq!(changes, 1);
}
let mut stmt = try!(conn.prepare("SELECT id, name FROM person"));
let snoc = |x, mut xs: Vec<_>| { xs.push(x); xs };
let ppl = try!(stmt.query_fold(
&[], vec!(), |row, ppl| {
Ok(snoc(Person {
id: row.get(0),
name: row.get(1)
}, ppl))
}));
Ok(ppl)
}