概要
Rust言語は最近書籍が発売されましたね.
mysql の設定など
関連packageのインストール
sudo apt-get install -y build-essential sudo apt-get install -y libssl-dev sudo apt-get install -y cmake
mysql と言ってけど嘘つきました.mariadbをインストールします.
sudo apt-get install mariadb-server mariadb-client
mysql の起動
sudo systemctl start mysql.service
無限にいいユーザーを作成
GRANT ALL PRIVILEGES ON *.* TO 'nwiizo'@'localhost' IDENTIFIED BY 'password';
良しなにDBを作成します.
MariaDB [(none)]> CREATE DATABASE dbtest; Query OK, 1 row affected (0.00 sec) MariaDB [dbtest]> use dbtest; Database changed MariaDB [dbtest]> CREATE TABLE `test` ( -> `id` bigint(20) NOT NULL AUTO_INCREMENT, -> `name` varchar(255) DEFAULT NULL, -> KEY `id` (`id`) -> ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.03 sec)
MariaDB [dbtest]> show databases; +--------------------+ | Database | +--------------------+ | dbtest | | information_schema | | mysql | | performance_schema | +--------------------+ 4 rows in set (0.00 sec) MariaDB [dbtest]> show tables; +------------------+ | Tables_in_dbtest | +------------------+ | test | +------------------+
Rustを良しなに変更して以下います.
Cargo.toml
[dependencies] mysql = "*"
src/main.rs
#[macro_use] extern crate mysql; // ... use mysql as my; #[derive(Debug, PartialEq, Eq)] struct Payment { customer_id: i32, amount: i32, account_name: Option<String>, } fn main() { let pool = my::Pool::new("mysql://nwiizo:password@localhost:3307/mysql").unwrap(); // Let's create payment table. // Unwrap just to make sure no error happened. pool.prep_exec(r"CREATE TEMPORARY TABLE payment ( customer_id int not null, amount int not null, account_name text )", ()).unwrap(); let payments = vec![ Payment { customer_id: 1, amount: 2, account_name: None }, Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) }, Payment { customer_id: 5, amount: 6, account_name: None }, Payment { customer_id: 7, amount: 8, account_name: None }, Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) }, ]; // Let's insert payments to the database // We will use into_iter() because we do not need to map Stmt to anything else. // Also we assume that no error happened in `prepare`. for mut stmt in pool.prepare(r"INSERT INTO payment (customer_id, amount, account_name) VALUES (:customer_id, :amount, :account_name)").into_iter() { for p in payments.iter() { // `execute` takes ownership of `params` so we pass account name by reference. // Unwrap each result just to make sure no errors happened. stmt.execute(params!{ "customer_id" => p.customer_id, "amount" => p.amount, "account_name" => &p.account_name, }).unwrap(); } } // Let's select payments from database let selected_payments: Vec<Payment> = pool.prep_exec("SELECT customer_id, amount, account_name from payment", ()) .map(|result| { // In this closure we will map `QueryResult` to `Vec<Payment>` // `QueryResult` is iterator over `MyResult<row, err>` so first call to `map` // will map each `MyResult` to contained `row` (no proper error handling) // and second call to `map` will map each `row` to `Payment` result.map(|x| x.unwrap()).map(|row| { // ⚠️ Note that from_row will panic if you don't follow your schema let (customer_id, amount, account_name) = my::from_row(row); Payment { customer_id: customer_id, amount: amount, account_name: account_name, } }).collect() // Collect payments so now `QueryResult` is mapped to `Vec<Payment>` }).unwrap(); // Unwrap `Vec<Payment>` // Now make sure that `payments` equals to `selected_payments`. // Mysql gives no guaranties on order of returned rows without `ORDER BY` // so assume we are lukky. assert_eq!(payments, selected_payments); println!("Yay!"); }
2018.08.21 mysqlのversion を* にするとregex1.0.2 が入り彼はbuildが失敗するみたいで.クソウケる. 任意のversionにすることをお勧めします