Rustを初めて触ってその流れでDBからデータ取得までを試してみた
とある理由で、ほぼ遊び感覚で、Rustを使う機会がありました。
多少勉強しましたが、新しく難しい概念に悩まされ、イマイチ理解は進みません。
とりあえず手を動かしたかったので、DB取得までをやってみました。
メモとして残しますが、もっとRustらしく書けるんだろうなと感じています。
rusqliteを使って、sqlite3からデータを取得し表示するまでです。
環境構築は本家を参考にしました。
www.rust-lang.org
以降は、 rustc 1.42.0-nightly
で動作確認済みです。
また、 my.db
という名前でsqlite3のDBを用意していて、スキーマ等は以下の通りです。
$ sqlite3 my.db sqlite> .schema users CREATE TABLE users (user_id int primary key, name text not null); sqlite> select * from users; 1|田中太郎 2|鈴木次郎
実際に書いたコードは以下です。
Cargo.toml
[package] name = "demo" version = "0.1.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rusqlite = "*"
main.rs
extern crate rusqlite; use rusqlite::{Connection, NO_PARAMS}; #[derive(Debug)] struct User { user_id: usize, name: String, } fn get_users() -> Vec<User> { let conn = Connection::open("my.db").unwrap(); let mut stmt = conn.prepare(" SELECT user_id, name FROM users ORDER BY user_id ASC ", ).unwrap(); let users = stmt.query_map(NO_PARAMS, |row| { Ok(User { user_id: row.get::<_, i64>(0).unwrap() as usize, name: row.get::<_, String>(1).unwrap(), }) }).unwrap(); let mut result: Vec<User> = vec![]; for user in users { result.push(user.unwrap()); } result } fn get_user(user_id: usize) -> Option<User> { let conn = Connection::open("my.db").unwrap(); let mut stmt = conn.prepare(" SELECT user_id, name FROM users WHERE user_id = ? ", ).unwrap(); let id = user_id as i64; let mut users = stmt.query_map(&[&id], |row| { Ok(User { user_id: row.get::<_, i64>(0).unwrap() as usize, name: row.get::<_, String>(1).unwrap(), }) }).unwrap(); let user = users.next(); match user { Some(user) => Some(user.unwrap()), None => None, } } fn main() { // 一覧取得 println!("{:?}", get_users()); // 存在するidを取得 println!("{:?}", get_user(1)); // 存在しないidを取得 println!("{:?}", get_user(999)); }
上記を実行すると以下のようになります。
$ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.02s Running `target/debug/demo` [User { user_id: 1, name: "田中太郎" }, User { user_id: 2, name: "鈴木次郎" }] Some(User { user_id: 1, name: "田中太郎" }) None
ユーザ一覧の取得とユーザ単体の取得(いる場合といない場合)についてうまくできました。
もうちょっとRustらしく書けそうなところもあり、 unwrap()
しすぎな感じもありますが、今後の自分に期待します。