小さい頃はエラ呼吸

いつのまにやら肺で呼吸をしています。


node.js × sqlite3でCRUDアプリケーションを作ってみたよ。

はじめに

node.jsとsqlite3でデータベースを使ったCRUDアプリケーションを試しに作ってみました。
この記事を書くにあたり、以下の記事を参考にさせていただきました。

サーバサイドJavaScript Node.js入門
清水俊博 大津繁樹 Jxck 小林秀和 佐々木庸平 篠崎祐輔 高木敦也 西山雄也
アスキー・メディアワークス
売り上げランキング: 172,346

ソフトウェアのバージョン
  • Mac OS X Mountain Lion 10.8.3
  • node.js v0.10.8
  • npm@1.2.23
  • express@3.2.5
  • sqlite3@2.1.7
  • sqlite3本体 3.7.15.2
事前準備

1. node.jsをインストールします。

wget http://nodejs.org/dist/node-latest.tar.gz
tar zxvf node-latest.tar.gz
cd node-v0.10.8/
./configure
make
sudo make install
node -v
>>v0.10.8

2. npmをインストールします。

sudo curl https://npmjs.org/install.sh | sudo sh

3. expressをグローバルインストールします。

sudo npm install express -g
アプリケーションのひな形を自動生成する

1. expressコマンドでサンプルアプリケーションのひな形を作ります。

express -e SampleApp

2. カレントディレクトリを移動しつつ、必要なライブラリを同時にインストールします。

cd SampleApp && npm install

express@3.2.5 node_modules/express
├── methods@0.0.1
├── fresh@0.1.0
├── range-parser@0.0.4
├── cookie-signature@1.0.1
├── buffer-crc32@0.2.1
├── cookie@0.1.0
├── debug@0.7.2
├── commander@0.6.1
├── mkdirp@0.3.4
├── send@0.1.0 (mime@1.2.6)
└── connect@2.7.10 (pause@0.0.1, qs@0.6.5, bytes@0.2.0, cookie@0.0.5, formidable@1.0.14)

3.npmコマンドでsqlite3のライブラリをインストールします。

npm install sqlite3

4.sqlite3でデータベースを作成します。

sqlite3 db.sqlite3

以下のSQLを流し、usersテーブルを作成します。

CREATE TABLE users (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT,
  furigana TEXT
);

以下のコマンドでsqlite3を終了させます。

.quit
app.jsの編集

app.jsは、app.getの次の行あたりにapp.postの行を追加します。

/**
 * Module dependencies.
 */

var express = require('express')
  , routes = require('./routes')
  , user = require('./routes/user')
  , http = require('http')
  , path = require('path');

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

app.get('/', routes.index);
// add start
app.post('/', routes.index);
// add end
app.get('/users', user.list);

http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});
index.ejs(UTF-8)

viewsディレクトリにあるindex.ejsを以下のように編集します。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>node.js × sqlite3で作るCRUDアプリケーション</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
    <script>
      function deleteRecord(obj) {
        document.getElementById("target").value = obj.value;
        document.getElementById("action").value = "delete";
        document.frm.submit();
      }
    </script>
  </head>
  <body>
    <h1>node.js × sqlite3で作るCRUDアプリケーション</h1>
    <p><%= messages %></p>
    
    <form action="/" method="post" name="frm">
    
    <fieldset style="width:450px">
    <legend>検索フォーム</legend>
    <input type="text" name="searchText" placeholder="%はワイルドカードとして扱われます。" style="width:250px"/>
    <button type="submit" name="submitBtn" value="search">検索</button>
    <button type="submit" name="submitBtn" value="reload">再表示</button>
    </fieldset>
    <br />
    <table border="1">
      <tr bgcolor="#cdcdcd" ><th> </th><th>id</th><th>名前</th><th>ふりがな</th></tr>
      <% users.forEach(function(user){ %>
      <tr>
      <td><button type="button" name="submitBtn" value="<%= user.id %>" onclick="deleteRecord(this)">削除</button></td>
      <td><%= user.id %></td><td><%= user.name %></td><td><%= user.furigana %></td>
      <% }) %>
      </tr>
    </table>
    <br />
    <hr />

    <fieldset style="width:350px">
    <legend>登録フォーム</legend>
    名前<input type="text" name="name" /><br />
    ふりがな<input type="text" name="furigana" /><br />
      
    <button type="submit" name="submitBtn" value="add">登録</button>
      
    <input type="hidden" id="target" name="target" value="" >
    <input type="hidden" id="action" name="action" value="" >
    </fieldset>
    </form>
  </body> 

</html>
index.js(UTF-8)

routesディレクトリにあるindex.jsを以下のように編集します。

var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('db.sqlite3');

exports.index = function(req, res){
  db.serialize(function(){
    var message = "";
    
    // レコードの登録
    if (req.body.submitBtn == "add") {
      db.run("INSERT INTO users (name, furigana) VALUES (?, ?)", req.body.name, req.body.furigana);
      message = "1件登録しました。";
    }
    
    // レコードの削除
    if (req.body.action == "delete") {
      db.run("DELETE FROM users WHERE id = ?", req.body.target);
      message = "1件削除しました。";
    }
    
    // 検索
    if (req.body.submitBtn == "search") {
      message = "検索結果を表示しました。";
      db.all("SELECT id, name, furigana FROM users WHERE name like '" + req.body. searchText + "'", function(err, rows){
        if (!err) {
         if(rows.length == 0) {
           message = "見つかりませんでした。";
         }
          res.render('index', {
            messages: message,
            users: rows
          }); 
        }
        else {
          console.log(err);
        }   
      }); 
    }
    // 全レコードを取得
    else {
      db.all("SELECT id, name, furigana FROM users", function(err, rows){
        if (!err) {
          res.render('index', {
            messages: message,
            users: rows
          }); 
        }
        else {
          console.log(err);
        }   
      });
    } 
  }); 
};
サンプルプログラムの動かし方

1. 以下のコマンドでサーバプログラムが起動します。

node app

2. ブラウザでhttp://localhost:3000/にアクセス。
完成したサンプルプログラムは、以下のような感じです。CRUDといいつつ、更新が実装できませんでした。