自分で作ったり提供したりするものは、まず自分自身で使ってみろろということです。自分じゃ使わないものなら人はいくらでも無責任にも無思考にもなれる。そういう投げやりな「サービス」やら「プロダクツ」なんて、だれだってイヤだ。自分が作り手と同時に利用者の立場になれば、ちゃんと使えるレベルのものを提供しようとします。

2013年10月22日火曜日

node.jsでhttpリクエストサンプル

Node.jsを使って、httpでウェブサイト内容をダウンロードする

var http = require('http');

var req = http.get('http://komanew.blogspot.jp', function(res){
    console.log(res.statusCode);
    console.log(res.headers.location);

    res.setEncoding('utf8');
    res.on('data', function(str) {
        console.log(str);
    });
});
req.on('timeout', function() {
    console.log('request timed out');
    req.abort()
});
req.on('error', function(err) {
    console.log("Error: " + err.code + ", " + err.message);
});

2013年10月20日日曜日

mongoose-virtualプロパティ

mongooseはバーチャルプロパティ(virtual property)をサポートしています、このトピックで紹介します。

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test01');

var PersonSchema = new mongoose.Schema({
  name:{
      first:String,
      last:String
  }
});
PersonSchema.virtual('name.full').get(function(){
    return this.name.first + ' ' + this.name.last;
});
PersonSchema.virtual('name.full').set(function(name){
    var split = name.split(' ');
    this.name.first = split[0];
    this.name.last = split[1];
});

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {

    var PersonModel = mongoose.model('Person',PersonSchema);

    var person1 = new PersonModel({
      name:{first:'koma',last:'endia'}
    });
    console.log("person1=" + person1.name.first + " " + person1.name.last);
    console.log("person1=" + person1.name.full);

    var person2 = new PersonModel({});
    person2.name.full = "koma endia";
    console.log("person2=" + person2.name.first + " " + person2.name.last);
    console.log("person2=" + person2.name.full);
});

javascriptコールバック例

Node.jsはコールバック関数をよく使われますので、コールバック簡単なサンプルをメモします。

function aaa(a, b, cb) {
    return cb(a, b);
}

function add(x, y) {
    return x+y;
}

console.log(add(1, 2));
console.log(aaa(2, 3, add));

$node callback.js
3
5

mongooseでMongoDBに接続してみる

前回と前々回はmongodbとmongoskinを使ってMongoDBに接続処理を紹介しました、今回はmongooseの使い方を紹介します。

Mongoose
http://mongoosejs.com/

まず、インストールします
npm install mongoose

MongoDBは何もせずに、直接にアクセスコードを書きます
nano mongoose.js
...
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test01');

var kittySchema = mongoose.Schema({
    name: String,
    age: Number
    });
kittySchema.methods.speak = function () {
  var greeting = this.name
      ? "Meow name is " + this.name : "I don't have a name"
  console.log(greeting);
}
kittySchema.statics.findAge10 = function(cb) {
  this.find({age:10}, cb);
}

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {
    var Kitten = mongoose.model('Kitten', kittySchema);
    var silence = new Kitten({ name: 'Silence', age: 10 });
    console.log(silence.name);
    silence.speak();

    silence.save(function(error, doc){
        if (error) throw error;

        doc.speak();
    });

    Kitten.find({age:10}, function(error, kittens){
        if (error) throw error;
        //console.log(kittens.length);
        for(var i = 0; i < kittens.length; i++) {
            console.log("name=" + kittens[i].name + ", age=" + kittens[i].age);
        }
    });
    Kitten.findAge10(function(error, kittens){
        if (error) throw error;
        for(var i = 0; i < kittens.length; i++) {
            console.log("[findAge10]" + "_id=" + kittens[i]._id + ", name=" + kittens[i].name + ", age=" + kittens[i].age);
        }
    });
});
...

express.jsのエラー処理

express.jsのエラー処理サンプルです。

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

var app = express();

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

//一般処理
app.use(function(request, response, next){
    console.log('ここだよ=[' + request.url + ']');
    response.send(404, "何もない");
});
//errorオブジェクトある処理
app.use(function(error, request, response, next) {
    //クライアントに送るHTTPコードです。基本はerrorオブジェクトにセットするべきですが、
    //セットされてない場合は、404をセットする
    response.status(error.status || 404);
    response.send("error.message=" + error.message);
});

app.get('/', routes.index);

//パラメーター処理例1
app.get('/user/:username', function(request, response, next){
    var username = request.params.username;
    if (username === 'koma') {
        next(); //404
    } else if (username === 'endia') {
        var err = new Error('該当するユーザーは存在していません。');
        //err.status = 500; //セットしたら、500を返す;セットしなければ、404を返す
        next(err);
    } else {
        response.send("ここは<strong>" + username + "</strong>さんのページです。");
    }
});

//パラメーター処理例2:チェック処理
app.param('postname', function(request, response, next, postname){
    if (postname === 'koma') {
        next(new Error(postname + "ポストは存在しません。")); //404
    } else {
        request.postname = postname;
        next();
    }
});
//パラメーターチェックOKだったら、ここへ
app.get('/post/:postname', function(request, response){
    response.send("this is <h1>" + request.postname + ".</h1>");
});

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

Express.jsサンプル

Express.jsフレームワークでウェブアプリケーションを開発するサンプルです。

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

var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(require('less-middleware')({ src: __dirname + '/public' }));
app.use(express.static(path.join(__dirname, 'public')));

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

app.get('/', function(request, response){
    response.send("helo express new aaabbb-bobopapa.");
});

app.get('/hi', function(request, response){
    response.send("<h1>hi</h1>");
});

app.get('/usrs/:userid', function(request, response){
    response.send("<h1>Helo, User " + request.params.userid + "</h1>");
});

app.get('/home', function(request, response){
    response.send(request.get('user-agent'));
});

app.param('from', function(request, response, next){
   request.from = parseInt(request.params.from, 10);
   next();
});

app.get('/user/:from-:to', function(request, response){
    var from = request.from;
    var to   = parseInt(request.params.to, 10);
    res.send("new.from=" + from + ", to=" + to);
});

var count = 0;
app.get('/helo.txt', function(request, response, next){
    //res.send("app.js helo.txt");
    count++;
    next();
});
app.get('/count', function(request, response, next){
    response.send(count + " views.");
});

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

2013年10月19日土曜日

node再起動せずに、直したコードを自動適用

通常はnode.jsコードを直して、[node app.js]を再起動しないと、適用されない問題あります。直したコードを即時に反映させるため、nodemonモジュールを利用して実現できます。

$vim package.json
...
  "scripts": {
    "start": "nodemon app.js"
  },
...
  "devDependencies": {
    "nodemon": "*"
  }
...

$npm install
npm http GET https://registry.npmjs.org/nodemon
npm http 200 https://registry.npmjs.org/nodemon
npm http GET https://registry.npmjs.org/nodemon/-/nodemon-0.7.10.tgz
npm http 200 https://registry.npmjs.org/nodemon/-/nodemon-0.7.10.tgz
nodemon@0.7.10 node_modules/nodemon

$npm start
> application-name@0.0.1 start /home/user/node/webapps/site1
> nodemon app.js
19 Oct 22:25:29 - [nodemon] v0.7.10
19 Oct 22:25:29 - [nodemon] to restart at any time, enter `rs`
19 Oct 22:25:29 - [nodemon] watching: /home/user/node/webapps/site1
19 Oct 22:25:29 - [nodemon] starting `node app.js`

2013年10月14日月曜日

MongoSkin基本使用

MongoDBにアクセスできるドライバーMongoskinの基本使い方です。

/**
 * Mongoskin
 * https://github.com/kissjs/node-mongoskin
 * http://www.hacksparrow.com/mongoskin-tutorial-with-examples.html
 */
// ライブラリ参照
var mongo = require('mongoskin');
// DB接続
var db = mongo.db('192.168.11.1:27017/blog_db', {
    safe : false
});
// コレクション取得
var users = db.collection('users');
// user検索
users.find({
    "name" : {
        $regex : /user-[0-4]/i
    }
}).toArray(function(error, band) {
    for ( var i = 0; i < band.length; i++) {
        console.log("name" + i + "=" + band[i].name);
    }
});
var threads = db.collection('threads');
var thread = {
    "title" : "title-4",
    "content" : "this is title-4 content."
};
// データ追加
threads.insert(thread, function(error, resultArray) {
    console.log("inserted thread title=" + JSON.stringify(resultArray));
    threads.find({}).each(function(error, thread) {
        if (thread !== null)
            console.log("thread title=" + thread.title);
    });
    // データ更新
    threads.update({
        "title" : "title-4"
    }, {
        $set : {
            "content" : "new title-4 content."
        }
    }, function(error, result) {
        console.log("object is updated.");
        threads.findOne({
            "title" : "title-4"
        }, function(error, thread) {
            console.log("thread4 new content=" + thread.content);
        });
    });
});
// データ削除
threads.remove({
    "title" : "title-4"
}, function(error, result) {
    console.log("object is removed.");
});
// データ件数取得
threads.count({}, function(error, count) {
    console.log("threads.count=" + count);
});

Node.jsで MongoDBにアクセスしてみる

node-mongodb-nativeドライバーを使ってNode.jsはドキュメント指向データベースMongoDBにアクセスするサンプルです。

MongoDBドライバーインストール
npm install mongodb

/**
 * MongoDB Access Sample http://mongodb.github.io/node-mongodb-native/
 */
var MongoClient = require('mongodb').MongoClient;

MongoClient.connect("mongodb://192.168.11.1:27017/blog_db", function(err, db) {
    // threadsコレクションオブジェクト作成
    var threads = db.collection('threads');
    // threadsデータクリア
    threads.remove({}, function(error, result) {
        console.log("removed result=" + result);
        // 追加データ用意
        var thread = [ {
            "title" : "title-1",
            "content" : "this is thread1 \"content\"."
        }, {
            "title" : "title-2",
            "content" : "this is thread2 \"content\"."
        }, {
            "title" : "title-3",
            "content" : "this is thread3 \"content\"."
        } ];
        threads.insert(thread, function(error, result) {
            console.log("inserted count=" + result.length);
            console.log("result[0].title=" + result[0].title);
            console.log("result[1].title=" + result[1].title);
            console.log("result[2].title=" + result[2].title);

            // 件数取得
            threads.count(function(error, count) {
                console.log('all threads count=' + count);
            });

            // title-2データ取得
            threads.findOne({
                "title" : "title-2"
            }, function(error, item) {
                if (error) {
                    throw error;
                }
                console.log("findOne({title-2})=" + item.content);

                // title-2データ更新
                threads.update({
                    "title" : "title-2"
                }, {
                    $set : {
                        "content" : "thread2 new content"
                    }
                }, function(error, result) {
                    console.log("updated result=" + result);

                    // 更新したデータを取得
                    threads.findOne({
                        "title" : "title-2"
                    }, function(error, item) {
                        console.log("updated thread2 content=" + item.content);
                    });
                });
            });
        });
    });
});

2013年10月13日日曜日

MongoDB基本使用

今日はドキュメント向けのデータベースMongoDBをいろいろと触りました、試したコマンドをメモします。

まず結論から言うと、MongoDBは本当に面白いデータベースです、今後のサイト構築は使うでしょう。

#mongodbシェルに入る
$mongo
#現在DB一覧
show dbs;
#利用DBに切り替える
use local
use blog_db;
#コレクション作成(テーブル)
db.createCollection("users");
show dbs;
#dbコマンドヘルプ
db.help();
#現在DB状態
db.stats();
#現在DB削除
db.dropDatabase();
#DB一覧
show dbs;

use blog_db;
db.createCollection("posts");
#コレクション一覧
show collections;
#コレクション削除
db.users.drop();
#コレクションリネーム
db.posts.renameCollection("threads");
#mongodbシェル終了
exit

#blog_dbに入る
$mongo blog_db
#コレクション一覧
show collections;
#usersコレクションにデータを追加
db.users.insert({"name":"koma","address":"tokyo","point":100});
#usersコレクションデータ検索
db.users.find();
#usersコレクションに違うスキマーデータを追加
db.users.insert({"name":"xiaoma", "skill":["linux","unix","mac os"]});
db.users.find();
#usersコレクション削除
db.users.remove();
db.users.find();

show collections;
db.users.find();
#大量データ追加(javascriptで)
for(var i = 0; i < 10; i++) {
db.users.insert({"name":"user-" + i, "group": i%3, "point": Math.floor(Math.random() * 100)});
}
db.users.find();

#検索条件付き(group=1)
db.users.find({"group":1});
#検索項目指定(name)
db.users.find({"group":1}, {"name":true});
#検索条件(group<>1)
db.users.find({"group":{$ne:1}}); //1以外を
#検索条件(point>40)
db.users.find({"point":{$gt:40}});
$gt >
$gte >=
$lt <
$lte <=
#検索条件(point>40 and point<60)
db.users.find({"point":{&gt:40, &lt:60}});
#検索条件(正規表現)
db.users.find({"name":{$regex:/user-[0-4]/i}});
#検索結果並び替え(point asc)
db.users.find().sort({"point":1}); // 1=asc;-1:desc
#SELECT TOP 1
db.users.findOne();
#検索件数制限(最初の3件)
db.users.find().limit(3);
#検索件数制限(3個目から3件)
db.users.find().skip(2).limit(3);
#検索件数
db.users.find().count();
#SELECT DISTINCT group
db.users.distinct("group");
#SELECT IN
db.users.find({"name":{$in:["user-3", "user-7"]}}); //in
#SELECT NOT IN
db.users.find({"name":{$nin:["user-3", "user-7"]}}); //not in
#データ追加
db.users.insert({"address":"my address content"});
#address項目存在のみデータ抽出
db.users.find({"address":{$exists:true}});

#インデックス情報取得
db.users.getIndexes();
#インデックス作成
db.users.ensureIndex({"point":1}); //1:asc;-1:desc
db.users.getIndexes();
#インデックス削除
db.users.dropIndex({"point":1});
db.users.getIndexes();
#唯一インデックス作成
db.users.ensureIndex({"name":1}, {"unique":true});
db.users.insert({"name":"user-5"});

#データ更新(CLEAR更新)
db.users.update({"name":"user-1"}, {"point":100});
db.users.find();
#データ更新(指定項目)
db.users.update({"name":"user-2"}, {$set:{"point":100}});
db.users.find();
#データ更新(数値累計)
db.users.find({"name":"user-3"}, {$inc:{"point":10}});
db.users.find();
#データ更新(項目削除)
db.users.update({"name":"user-4"}, {$unset:{"point":1}});
db.users.find();
#データ更新(項目名変更)
db.users.update({"name":"user-5"}, {$rename:{"group":"mygroup"}});
db.users.find();

#データあれば更新、なければ作成
db.users.update({"name":"user-10"}, {$inc:{"point":10}}, true); //upsert
db.users.find();
#最初の1件だけ+100
db.users.update({}, {$inc:{"point":100}});
#全件+100
db.users.update({}, {$inc:{"point":100}}, false, true);

#コマンドバッチ作成
$nano batch.js
...
db.users.remove({"name":"user-10"});
...
#バッチ実行(コマンドライン)
$mongo blog_db batch.js
$mongo blog_db
db.users.find();
#バッチ実行(load関数)
load("batch.js"); //load script
db.users.find();

#DBバックアップ
$mongodump --db blog_db
#DBリストア
$mongorestore --drop

ホームページ