2012年11月27日 星期二

Using mysql in Node.js

人人都有一套 ORM,
補充一下, JavaScript 其實有支援 Getter, Setter,

另外,根據不可靠消息,看一下各種不同 MySQL Node.js client 效能差異。



Using mysql in Node.js

寫SQL的人通常都會遇到一次一個table有很多欄位的狀況
傳統的方式是透過sql的prepare statement
再透過一個一個的set來設定那些問號(prepare statement中的值帶入方式,一般都以"?"來代表有值耀輸入)
有別於傳統,在物件導向程式語言中可以透過setter的方式來建立欄位
再透過像Hibernate的資料庫framework將資料一次鍵入DB
但Node.js中則沒那麼多規則...
但是如果要處理一堆問號跟參數的傳入,又不想要眼花...可以透過一些"方法"...


目的在提供一個可以重複利用的模組,讓任何require進來的程式可以直接操作 
# vi sql.js
var util = require('util');                                                                                                                                            
function buildSql(params){
  var sql = "insert into xxxx (%s) values (%s)";
  var k = '', v = '';
  var arr = Object.keys(params);
  var cond = [];
  for(var i = 0 ; i < arr.length ; i++){
      k += arr[i] ;
      v += '?';
      if(i < arr.length -1){
        k += ',';
        v += ',';
      }
      cond.push(params[arr[i]]);
  }
  var finalsql = util.format(sql,k,v)
  return {sql:finalsql, cond:cond};
}
exports.buildSql = buildSql;


實作測試
# testSql.js
var sql = require('./sql');                                                                                                                                            
var opt = {}
opt["k1"] = 'v1';
opt["k2"] = 'v2';
var s = sql.buildSql(opt);
console.log(JSON.stringify(s));


結果輸出
# node testSql.js 
{"sql":"insert into xxxx (k1,k2) values (?,?)","cond":["v1","v2"]}


延伸這樣的組和參數與欄位的方式
也可以開發一套lib作為Node.js的Hibernate喔∼

2012年11月26日 星期一

透過某種"方式"讓Node.js程式順序執行

var exec = require('child_process').exec;

var arr = [1,2,3,4,5,6,7];
                      
function doit(v){
  exec('echo ' + v, function(err, stdo, stde){
    console.log('-->' + stdo);
    if(arr.length >0) //如果array還有值,則再call一次本身
      doit(arr.pop());
  });
}

doit(arr.pop());

執行結果:
# node test.js 
-->7
-->6
-->5
-->4
-->3
-->2
-->1

2012年11月25日 星期日

Node.js的forEach迴圈非循序進行

Node.js的forEach迴圈非循序進行:

var arr = [1,2,3,4,5,6,7]

arr.forEach(function(v,i){
  exec('echo ' + arr[i], function(err, stdo, stde){
    console.log('-->' + stdo);
  });
});

執行1:
# node test.js 
-->6
-->5
-->4
-->3
-->2
-->1
-->7

執行2:
# node test.js 
-->5
-->4
-->3
-->2
-->1
-->7
-->6

2012年11月20日 星期二

使用smartos建立node.js之ssl web server

下面展示使用micloud smartos建立node.js之ssl web server
smartos在建立起來時候,會自動產生一組selfsigned.pem的key
可以省去建立openssl的時間...
設定node.js https時候,可以直接將key與cert都指定在selfsigned.pem上
透過該key提供ssl需要的認證金鑰...

Step 1:
# express ssltest && cd ssltest && npm install

Step 2:
# vi app.js

var express = require('express')
  , routes = require('./routes')
  , https = require('https') //使用node.js https模組
  , fs = require("fs")
  , path = require('path');

//設定https需要使用的options參數
var key = '/opt/local/etc/openssl/private/selfsigned.pem';
var crt = key; 
var privateKey = fs.readFileSync(key);
var certificate = fs.readFileSync(crt);
var options = {
    key: privateKey,
    cert: certificate,
};

var app = express();

app.configure(function(){
  app.set('port', process.env.PORT || 1330);
  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(express.static(path.join(__dirname, 'public')));
});

app.configure('development', function(){
  app.use(express.errorHandler());
});

app.get('/', routes.index); //express default root

//建立一個測試route
app.get('/test', function(req, res){
  res.writeHead(200);
  res.end('TEST...');
});

//使用https來建立server, 建立過程中帶入options參數
https.createServer(options, app).listen(app.get('port'), function(){
  console.log("Express server listening on port " + app.get('port'));
});

Step 3 - 測試:
# node app.js

打開Browser連線:https://your.ip.address:1330/test



參考:


2012年11月3日 星期六

NodeJS connect Couchdb

CouchDB是NoSQL資料庫的一支,由Apache維護...(這是我選他的最大原因)
預設CouchDB提供RESTful server,並由該Server作為所有API的接口
同時Apache也有許多專案實作接入CouchDB的各市程式語言的API

本篇以想使用Node.js連接Couchdb的部分為教學
假設大家已經有Node.js以及Couchdb的服務...

安裝Cradle套件
# npm install cradle

設定cradle連線couchdb的connection
  db = new(cradle.Connection)(db_address, db_port, {
    auth: { username: dbusername, password: dbpassword },
    cache: true,
    raw: false
  }).database(databasename);
上述建構連線資料庫的基本資訊,包含資料庫位置、port號、帳號、密碼等資訊。

而Couchdb的新刪改查說明如下:

新增一筆資料,id=PK,doc=欲儲存文件,callback=儲存結束後回傳:
db.save(id, doc, callback);

刪除一筆資料,id=PK,rev=版本號碼,callback同上:
db.remove(id, rev, callback);

修改一筆資料,id=欲修改之資料id,doc=欲修改的文件內容,callback同上:
db.merge(id, doc, callback);

查詢一筆資料,id=欲查詢的資料id,callback為查詢回傳,包含查詢結果:
db.get(id, callback);


下面為一個整體的資料庫查詢範例,您可以修改內部的一些實作來變成專案中處理CouchDB的幫手∼

var util = require('util')                                                                                                                                
  , cradle = require('cradle')
  , dbusername = 'your_db_username'
  , dbpassword = 'your_db_password'
  , databasename = 'your_db_name'
  , db_address = 'your.db.address'
  , db_port = 'your_db_port' //default: 5984
  , db = new(cradle.Connection)('http://' + db_address, db_port, {
    auth: { username: dbusername, password: dbpassword },
    cache: true,
    raw: false
  }).database(databasename);

//如果要做到查詢模組∼
exports.queryExample = function(id, callback) {
console.log('Query of %s', id);
db.get( id, function (err, doc) {
if(err) console.log(err);
callback(err, doc);
});
}
/*
ex: sample data: {_id:"simon","_rev":"3-f84647507bd83e29a6deae7c377a74dc","first_name":"simon","last_name":"su"}
this.queryExample('simon',function(err, doc){
...
})
*/

//如果要做到查尋View∼
exports.queryViewExample = function(id, callback) {
console.log('Query of %s', id);
db.view( 'domain/userDomain',{key: userid}, function (err, doc) {
if(err) console.log(err);
callback(err, doc);
});
}
/*
ex: sample data: [{key:"simon", value:{....}},{key:"jelly", value:{....}},{key:"kimi", value:{....}}...]
this.queryViewExample('simon',function(err, doc){
...
})
*/

//如果要建立一筆資料∼
exports.createExample = function(id, doc, callback) {
db.save(id, doc, function(err, res){
if(err) console.log(err);
callback(err, res);
});
}
/*
ex: sample input doc={name:"simon",phone:"0953609275"}
this.createExample(id, doc, function(err, res){
...
});
*/

//如果要更新一筆資料∼
exports.updateExample = function(id, doc, callback) {
db.merge(id, doc, function (err, res) {
if(err) console.log(err);
callback(err, res);
});
}
/*
ex: sample update data id=key_of_row, doc={...}
this.updateExample(id, doc, function(err, res){
...
});
*/


/** 其他範例:
//Create Database:
var db = c.database('database_name');
db.create();

//Delete Database
db.destroy(callback);

更多範例請參考:https://github.com/cloudhead/cradle
**/