以前、Python の Flask からインスパイアされた C++ 製のとてもかっちょいい WAF「crow」を紹介しました。
Big Sky :: C++ 製 micro web framework「crow」を使って lingr の bot 書いてみた。
先日、github で crow という、python の flask からインスパイアされた C++ 製 micro web framework を見つけました。 ipkn/crow - GitHu...
http://mattn.kaoriya.net/software/lang/c/20140718122410.htm
ipkn/crow - GitHub
https://github.com/ipkn/crow
ひさびさ見てみたら、mustache テンプレートエンジンをサポートしていました。
{{ mustache }}
Logic-less templates
http://mustache.github.io/
さらに amalgamate というフォルダには1ファイルだけで使えるヘッダファイルも用意されています。
これはすごい。前回は lingr のボットを作ってみましたが、今回は MySQL を使った1行掲示板を書いてみました。
まず DDL は以下の通り。
CREATE TABLE bbs (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
text VARCHAR(100),
created TIMESTAMP DEFAULT NOW()
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
掲示板のコードは以下の通り。
#include <memory>
#include <mysql_connection.h>
#include <mysql_driver.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/resultset.h>
#include "crow_all.h"
int
main() {
std::ifstream conf("config.json");
if (!conf) {
std::cerr << "config.json not found" << std::endl;
return 1;
}
std::string json = {
std::istreambuf_iterator<char>(conf),
std::istreambuf_iterator<char>()};
crow::json::rvalue config = crow::json::load(json);
auto driver = sql::mysql::get_mysql_driver_instance();
auto raw_con = driver->connect(
(std::string) config["db_host"].s(),
(std::string) config["db_user"].s(),
(std::string) config["db_pass"].s());
auto con = std::unique_ptr<sql::Connection>(raw_con);
con->setSchema((std::string) config["db_name"].s());
crow::SimpleApp app;
crow::mustache::set_base(".");
CROW_ROUTE(app, "/")
([&]{
auto stmt = std::unique_ptr<sql::PreparedStatement>(
con->prepareStatement("select * from bbs order by created"));
auto res = std::unique_ptr<sql::ResultSet>(
stmt->executeQuery());
int n = 0;
crow::mustache::context ctx;
while (res->next()) {
ctx["posts"][n]["id"] = res->getInt("id");
ctx["posts"][n]["text"] = res->getString("text");
n++;
}
return crow::mustache::load("bbs.html").render(ctx);
});
CROW_ROUTE(app, "/post")
.methods("POST"_method)
([&](const crow::request& req, crow::response& res){
crow::query_string params(req.body);
auto stmt = std::unique_ptr<sql::PreparedStatement>(
con->prepareStatement("insert into bbs(text) values(?)"));
stmt->setString(1, params.get("text"));
stmt->executeUpdate();
res = crow::response(302);
res.set_header("Location", "/");
res.end();
});
app.port(40081)
//.multithreaded()
.run();
}
/
で一覧表示、/post
で投稿します。MySQL の操作は MySQL Connector/C++ を使いました。
MySQL :: MySQL Connector/C++ Developer Guide
Table of Contents [ +/- ] Preface and Legal Notices 1 Introduction to MySQL Connector/C++ 2 How to G...
http://dev.mysql.com/doc/connector-cpp/en/
HTML (mustache) は以下の通り。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>一行掲示板</title>
</head>
<body>
<h2>一行掲示板</h2>
<ul>
{{# posts}}
<li>{{id}}: {{text}}</li>
{{/ posts}}
</ul>
<form action="/post" method="post">
<input type="text" name="text"><input type="submit">
</form>
</body>
</html>
あとは MySQL への接続情報が書かれた config.json
を用意すれば
{
"db_host": "localhost",
"db_user": "mysqluser",
"db_pass": "mysqlpass",
"db_name": "bbs"
}
この様な1行掲示板が出来ました。もちろん入力チェック等は行っていませんので実際にはもう少しコードが長くなります。
crow、かっちょいいですね。
いつも通り、コードは github に置いておきます。
mattn/crow-bbs - GitHub
https://github.com/mattn/crow-bbs