Skip to content

Instantly share code, notes, and snippets.

@chuck0523
Created September 18, 2016 14:54
Show Gist options
  • Save chuck0523/37e2c63ec55e3d2669461fe6784a76fd to your computer and use it in GitHub Desktop.
Save chuck0523/37e2c63ec55e3d2669461fe6784a76fd to your computer and use it in GitHub Desktop.
const r = require('rethinkdb')
const express = require('express')
const async = require('async')
const bodyParser = require('body-parser')
const config = require(__dirname + '/config')
const app = express()
// index.htmlとその他のフロントエンドアセットをサーブする。
app.use(express.static(__dirname + '/public'))
app.use(bodyParser.json())
/*
* すべてのTodoアイテムを取得
*/
const listTodoItems = (req, res, next) => {
r.table('todos').orderBy({index: 'createdAt'}).run(req.app._rdbConn, (err, cursor) => {
if(err) {
return next(err)
}
cursor.toArray((err, result) => {
if(err) {
return next(err)
}
res.json(result)
})
})
}
/*
* 新しくTodoを作成してinsert
*/
const createTodoItem = (req, res, next) => {
const todoItem = req.body
todoItem.createAt = r.now()
console.dir(todoItem)
r.table('todos').insert(todoItem, {returnChanges: true}).run(req.app._rdbConn, (err, result) => {
if(err) {
return next(err)
}
res.json(result.changes[0].new_val)
})
}
/*
* 特定のTodoを取得
*/
const getTodoItem = (req, res, next) => {
const todoItemID = req.params.id
r.table('todos').get(todoItemID).run(req.app._rdbConn, (err, result) => {
if(err) {
return next(err)
}
res.json(result)
})
}
/*
* Todoの更新
*/
const updateTodoItem = (req, res, next) => {
const todoItem = req.body
const todoItemID = req.params.id
r.table('todos').get(todoItemID).update(todoItem, {returnChanges: true}).run(req.app._rdbConn, (err, result) => {
if(err) {
return next(err)
}
res.json(result.changes[0].new_val)
})
}
/*
* Todoの削除
*/
const deleteTodoItem = (req, res, next) => {
const todoItemID = req.params.id
r.table('todos').get(todoItemID).delete().run(req.app._rdbConn, (err, result) => {
if(err) {
return next(err)
}
res.json({success: true})
})
}
/*
* page-not-found ミドルウェア
*/
const handle404 = (req, res, next) => {
res.status(404).end('not found')
}
/*
* 500ページを送り返し、エラーをロギングする
*/
const handleError = (err, req, res, next) => {
console.error(err.stack)
res.status(500).json({err: err.message})
}
/*
* DB接続をストアして、ポートのリッスンを始める
*/
const startExpress = (connection) => {
app._rdbConn = connection
app.listen(config.express.port)
console.log(`Listening on port ${config.express.port}`)
}
// ルーティング定義
app.route('/todos')
.get(listTodoItems)
.post(createTodoItem)
app.route('/todos/:id')
.get(getTodoItem)
.put(updateTodoItem)
.delete(deleteTodoItem)
app.use(handle404)
app.use(handleError)
/*
* RethinkDBに接続して、必要なテーブルを作成してインデックスを貼り、expressを起動する
*/
async.waterfall([
// RethinkDBに接続
function connect(callback) {
r.connect(config.rethinkdb, callback)
},
// DBを無ければ作成
function createDatabase(connection, callback) {
r.dbList().contains(config.rethinkdb.db).do((containsDb) => {
return r.branch(
containsDb,
{created: 0},
r.dbCreate(config.rethinkdb.db)
)
}).run(connection, (err) => {
callback(err, connection)
})
},
// テーブルを無ければ作成
function createTable(connection, callback) {
r.tableList().contains('todos').do((containsTable) => {
return r.branch(
containsTable,
{created: 0},
r.tableCreate('todos')
)
}).run(connection, (err) => {
callback(err, connection)
})
},
// インデックスが無ければ作成
function createIndex(connection, callback) {
r.table('todos').indexList().contains('createdAt').do((hasIndex) => {
return r.branch(
hasIndex,
{created: 0},
r.table('todos').indexCreate('createdAt')
)
}).run(connection, (err) => {
callback(err, connection)
})
},
// インデックスをwaitさせる
function waitForIndex(connection, callback) {
r.table('todos').indexWait('createdAt').run(connection, (err, result) => {
callback(err, connection)
})
}
], (err, connection) => {
if(err) {
console.error(err)
process.exit(1)
return
}
// express起動
startExpress(connection)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment