Posted on 2025/01/25, 5:13 PM By admin22
RustでSQLiteを扱うためのライブラリ、Rusqliteを試してみました。
Rusqliteを知ったのも、コードを書いたのも、ChatGPTとの対話からです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
use rusqlite::{params, Connection, Result}; fn main() -> Result<()> { // SQLiteデータベースに接続(ファイルが存在しない場合は作成される) let conn = Connection::open("sample.db")?; // テーブルを作成 conn.execute( "CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL UNIQUE )", [], )?; /* // データを挿入 conn.execute( "INSERT INTO users (name, email) VALUES (?1, ?2)", params!["Alice", "alice@example.com"], )?; conn.execute( "INSERT INTO users (name, email) VALUES (?1, ?2)", params!["Bob", "bob@example.com"], )?; */ insert_user_if_not_exists(&conn, "Alice", "alice@example.com")?; insert_user_if_not_exists(&conn, "Bob", "bob@example.com")?; insert_user_if_not_exists(&conn, "Alice", "alice@example.com")?; // 重複 // データを取得 /* let mut stmt = conn.prepare("SELECT id, name, email FROM users")?; let user_iter = stmt.query_map([], |row| { Ok(User { id: row.get(0)?, name: row.get(1)?, email: row.get(2)?, }) })?; // データを表示 println!("Users in the database:"); for user in user_iter { println!("{:?}", user?); } */ // データを取得して構造体に格納 let users = fetch_users(&conn)?; for user in users { //println!("{:?}", user); // 各フィールドを展開して表示 println!( "ID: {}, Name: {}, Email: {}", user.id, user.name, user.email ); } Ok(()) } // データを保持するための構造体 #[derive(Debug)] struct User { id: i32, name: String, email: String, } fn insert_user_if_not_exists(conn: &Connection, name: &str, email: &str) -> Result<()> { if !is_duplicate(conn, "users", "email", email)? { insert_user(conn, name, email)?; println!("Inserted: {}, {}", name, email); } else { println!("Email '{}' already exists. Skipping insert.", email); } Ok(()) } fn is_duplicate(conn: &Connection, table: &str, column: &str, value: &str) -> Result<bool> { let query = format!( "SELECT EXISTS(SELECT 1 FROM {} WHERE {} = ?1)", table, column ); let exists: bool = conn.query_row(&query, params![value], |row| row.get(0))?; Ok(exists) } fn insert_user(conn: &Connection, name: &str, email: &str) -> Result<()> { conn.execute( "INSERT INTO users (name, email) VALUES (?1, ?2)", params![name, email], )?; Ok(()) } /// データベースから`User`構造体のリストを取得する関数 fn fetch_users(conn: &Connection) -> Result<Vec<User>> { let mut stmt = conn.prepare("SELECT id, name, email FROM users")?; let user_iter = stmt.query_map([], |row| { Ok(User { id: row.get(0)?, name: row.get(1)?, email: row.get(2)?, }) })?; // 結果をベクタに変換 let users: Vec<User> = user_iter.filter_map(Result::ok).collect(); Ok(users) } |
コメントの部分は、修正前のコードを残しています。
存在のチェックをしたり、関数化をしたり、ChatGPTにリクエストしています。
構造体のメンバーを使っていないことからワーニングが出ていたため、構造体に格納するよに指示しました。
Rustは構文チェックが厳しくエラーが出やすいのですが、ChatGPTの活用でストレスが少なくなります。
Categories: 未分類 タグ: Rust, SQL