中編で棚上げしていたsync
メソッドを提供するAPIの実装を書いていこう。
Sequelizeのサンプルを見てもわかるように、sync
メソッドはimport
メソッドによってインスタンス化されたモデルオブジェクトに対する呼び出し(Project.sync
)と、Sequelize
オブジェクトに対する呼び出し(sequelize.sync
)の2パターンある。モデルオブジェクトに対してsync()
を実行すると、対応するテーブル定義だけが構築される。 Sequelizeオブジェクトに対してsync()
を実行すると、データベース全体が構築される。また、sync()
の引数に{ force: true }
を渡すと、既存のテーブルを一旦削除(DROP)してゼロからテーブルを作り直す(再構築)。
APIとしては、個々のテーブル(モデルオブジェクト)に対する呼び出しと、全体(Sequelizeオブジェクト)に対する呼び出しを分けて提供する。それぞれのメソッド名を/devel/sync/:table
、/devel/sync
として、routes/index.js
に以下のコードを追加しよう。
module.exports = function(app, config) { var sequelize = require('dbconn')(config) , models = require('models')(sequelize); // Database migration app.configure('development', function() { var sync = require('./sync'); app.post('/devel/sync/:table', sync.one(models)); app.post('/devel/sync', sync.all(sequelize)); }); app.resource('users', require('./users'), { id: 'id' }); };
sync
メソッドを使うのはあくまで開発過程だけであって、リリースしたときにAPIを叩かれてしまってはたまらないので、development
環境でだけ動作するようにしておく。また、ブラウザからうっかりAPIを叩くことがないように、HTTPメソッドもPOSTのみ受け付けるようにしておく。
続いてroutes/sync.js
にsync
モジュールを実装していく。
var done = function(res) { return function() { res.send('Done.\n'); }; }, dberr = function(res) { return function(e) { res.statusCode = 500; res.send(e); }; }; module.exports = { all: function(sequelize) { return function(req, res) { sequelize.sync(req.body).success(done(res)).error(dberr(res)); }; }, one: function(models) { return function(req, res) { var model = models[req.params.table]; if(model != undefined) { model.sync(req.body).success(done(res)).error(dberr(res)); } else { res.send(404); } }; } };
繰り返すが、開発過程で使うものなので、正常時、エラー時の出力は自分がわかるレベルでよい。
さぁ、これで準備が整った。中編でmodels/users.js
で実装したUser
モデル定義を思い出してほしい。モデル定義をしただけでデータベース上にはまだテーブル定義がない状態である。
まずはnodeを起ち上げておく。
$ NODE_PATH=libs node app.js
別ターミナルを開いて、いま実装したsync
モジュールのAPIを実行してみよう。
$ curl -X POST localhost:3000/devel/sync Done.
nodeを起ち上げたターミナルには、テーブルが構築された際に実行されたSQL文がダンプされているはずだ。
$ NODE_PATH=libs node app.js Sequelize connecting to test on localhost as h2plus Express server listening on port 3000 in development mode Executing: CREATE TABLE IF NOT EXISTS `users` ( `userame` VARCHAR(255), `password` char(40), `id` INTEGER NOT NULL auto_increment , `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB;
models/users.js
では、id
、createdAt
、updatedAt
というカラムを定義していないが、これはSequelizeが(勝手に)生成しているものである。
mysqlshow
コマンドを実行して、実際にテーブルができていることを確認してみるといいだろう。
$ mysqlshow -u h2plus -p test users
users
テーブルだけ構築するならば、
$ curl -X POST localhost:3000/devel/sync/users
を実行すればいい。
User
モデルの定義を途中で変更して、テーブルを再構築したい場合は、
$ curl -X POST -d 'force=1' localhost:3000/devel/sync/users
を実行すれば、sequelize.sync({ force: true })
が実行されるようになる。
あとは、アプリケーションのモデル定義をmodels
配下に追加していき、routes/index.js
にロジックを実装していくだけである。
2 コメント