Let's write β

プログラミング中にできたことか、思ったこととか

RustでWebプログラミング No.4 ~ MySQLに接続する~

振り返り

前回

poketo7878-dev.hatenablog.com

は、HandlebarでHTMLページをテンプレートから生成し、表示するというところまで作りました。今回は、MySQLに接続してデータを取得し、それをテンプレートに埋め込んで表示するということをやりました。

Iron-R2D2-Mysql-MiddlewareをCargo.tomlについか

Rust界隈はどうも主要なデータベースツール周りがPostgresをメインにサポートしていることが多いようで、MySQLをサポートしているツールがあまりない印象です。

そこで、拙作の

github.com

を利用します。これはIronのMiddlewareでR2D2-MySQLというコネクションプールライブラリを利用して、リクエストハンドラ中からMySQLへのコネクションを利用することを可能にするものです。

[dependencies]
iron = "0.4.0"
router = "0.4.0"
handlebars-iron = "0.18.0"
params = "0.4.1"
r2d2 = "0.7.0"
r2d2_mysql="*"
iron-r2d2-mysql-middleware = { git = "https://github.com/pocket7878/iron-r2d2-mysql-middleware.git" }


[dependencies.mysql]
version = "3.0.0"
default-features = false
features = ["socket"]

ChainへのMiddlewareの追加

extern crate iron_r2d2_mysql_middleware;

...

use iron_r2d2_mysql_middleware::{MysqlMiddleware, MysqlReqExt};

まず、iron_r2d2_mysql_middlewareを利用可能にして下さい。

そして、

let mysql_middleware = MysqlMiddleware::new("mysql://root:12345678@localhost/test").unwrap();
chain.link_before(mysql_middleware);

のように、MysqlMiddlewareを作成して前回同様, MiddlewareのChainに追加して下さい。 今回のこのMiddlewareはリクエストがメインのハンドラに落ちるに、 コネクションプールにつなぐための準備を設定するものなので、BeforeMiddlewareと呼ばれるものになっています

前回の、HandlebarのMiddlewareはハンドラが処理を行ったに、レスポンスの中身をみて、 Templateが設定されていたら処理するものなので、AfterMiddlewareになっています。

そのため、Chainへの追加の方法がlink_beforeであることに注意して下さい。

ハンドラ中でのMySQLへの接続

まず、コード全体は以下のとおりです:

    fn user_index(req: &mut Request) -> IronResult<Response> {
        let mut resp = Response::new();
        let mut data = HashMap::new();
        let mut con = req.db_conn();
        let mut users = vec![];
        for result in con.prep_exec("SELECT id, first_name, last_name FROM users", ()).unwrap() {
            let mut row = result.unwrap();
            let mut user_data: HashMap<String, String> = HashMap::new();
            let user_id: u64 = row.take("id").unwrap();
            let last_name: String = row.take("last_name").unwrap();
            let first_name: String = row.take("first_name").unwrap();
            user_data.insert(String::from("user_id"), format!("{}", user_id));
            user_data.insert(String::from("user_name"), format!("{} {}", last_name, first_name));
            users.push(user_data);
        }
        data.insert(String::from("users"), users);
        resp.set_mut(Template::new("user_index", data)).set_mut(status::Ok);
        return Ok(resp);
    }

肝となるのは

let mut con = req.db_conn();

の部分です、これで、コネクションプールからMySQLへの接続を1つ取り出してきています。 このインスタンス

outersky.github.io

インスタンスとなっています。 このインスタンスを利用して、クエリを発行し、データベースから取り出した値を利用してuser_indexテンプレートに流してやっています。