我自己比較常用的database還是mysql,所以先用他來測試一下在伺服器中使用資料庫引擎。
mysql模組
稍微找了一下資料,目前看起來比較成熟的獨立mysql模組看起來有:
其中,node-mysql看起來在不同作業系統跑應該都沒問題,而node-mysql-libmysqlclient看起來好像必須有libmysqlclient,不知道在windows上跑是否沒問題,所以就先拿node-mysql來測試。用npm安裝也很容易,只要在console使用npm install -g mysql
就可以安裝好。
驗證
先建立一個測試資料庫(node_test)跟一些測試資料:
CREATE TABLE IF NOT EXISTS `authors` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(20) NOT NULL,
`email` varchar(30) NOT NULL,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `group_id` (`group_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `authors` (`id`, `name`, `email`, `group_id`) VALUES
(1, 'name1', 'name1@email.com', 1),
(2, 'name2', 'name2@email.com', 1),
(3, 'name3', 'name3@yupa.com', 2),
(4, 'name4', 'name4@yupa.com', 2);
CREATE TABLE IF NOT EXISTS `configs` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(20) NOT NULL,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `configs` (`id`, `name`, `value`) VALUES
(1, 'title', 'test for mysql');
CREATE TABLE IF NOT EXISTS `groups` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `groups` (`id`, `name`) VALUES
(1, 'group1'),
(2, 'group2');
然後用兩個查詢來把資料找出來:
var mysql = require('mysql');
var client = mysql.createClient({
user: 'root',
password: '',
host: '127.0.0.1',
port: '3306',
database: 'node_test'
});
function Wait(count, cb) {
var limit = 0;
var payload = [];
this.next = function(data) {
payload.push(data);
count--;
if(count<=0) {
cb(payload);
}
}
}
var sync = new Wait(2, function(obj) {
var i=0;
var ret = {};
for(; i<obj.length; i++) {
if(obj[i][0].title) {
ret.title = obj[i].title;
} else {
ret.rows = obj[i]
}
}
console.log(ret);
client.end();
});
client.query("SELECT `value` as title FROM `configs` WHERE name='title'", function(err, results, fields) {
if(!err) {
sync.next(results);
} else {
console.log('err 1.');
}
});
client.query("SELECT a.name AS `group`, b.name AS name, b.email AS email FROM groups AS a LEFT JOIN authors AS b ON b.group_id=a.id WHERE 1", function(err, results, fields) {
if(!err) {
sync.next(results);
} else {
console.log('err 2.');
}
});
查詢很簡單,但是結果是用非同步的方式傳給callback,要在兩個查詢結束才回傳結果會有點麻煩。所以把它用一個Wait物件來處理,讓兩個查詢都執行完畢後,才處理查詢的結果。(這類的問題,尤其在資料庫查詢的時候,會常常碰到)
接下來就要執行看看:
D:\fillano\Dropbox\Shared\tests>node testMysql.js
{ title: undefined,
rows:
[ { group: 'group1', name: 'name1', email: 'name1@email.com' },
{ group: 'group1', name: 'name2', email: 'name2@email.com' },
{ group: 'group2', name: 'name3', email: 'name3@yupa.com' },
{ group: 'group2', name: 'name4', email: 'name4@yupa.com' } ] }
看起來查詢的結果符合預期,可以進一步放進伺服器中做測試。
整合
接下來要調整一些檔案來做測試,首先是template檔,在test目錄中新增一個測試用的template,temp2.html,跟temp1.html差不太多,只是跟目前model調整匹配。
<title>{{title}}</title>
<table border="1" cellspacing="0" cellpadding="2">
{%for row in rows%}
<tr><td>{{row.group}}</td><td>{{row.name}}</td><td>{{row.email}}</td></tr>
{%endfor%}
</table>
在vies.js增加一個view:
"hello_mvc1": function(cb) {
var view = swig.compileFile('tests/temp2.html');
this.render = function(data) {
cb(false, '/hello_mvc1', {type:'text/html', data: view.render(data)});
};
}
把剛剛測試的程式加入到models.js中,請參考:https://github.com/fillano/evolve/blob/61db226871bee024cf7bf149c5571811311e487b/tests/models.js 的37~68行。
最後調整testServer.js,在setUp增加一個router:
.get('/hello_mvc1', function (request, response, cb) {
var HelloModel = require('./models')['hello_mvc1'];
var HelloView = require('./views')['hello_mvc1'];
var m = new HelloModel(new HelloView(cb));
m.execute();
})
針對這個router寫一個測試,請參考:
https://github.com/fillano/evolve/blob/61db226871bee024cf7bf149c5571811311e487b/tests/models.js 的230~258行。
然後用ant integrate跑測試,看起來結果OK。
今天的範例檔fillano-evolve-v0.0.20-0-g61db226.zip,目前版本是v0.0.20。