夢想偉大,但步伐短小的 DBHouse
數個月前開始做一個計劃『AppHouse』,實作如 Google App Engine(GAE) 般的 PaaS,其志在打造自己的 Node.js 雲端軟體平台。然後發現,除了讓雲端服務可以在平台上跑起來外,資料庫管理也必需有個便於使用的機制和規劃,仔細想想,一個沒有資料庫配合的雲端服務,可沒有什麼太大的價值,於是,『DBHouse』便應運而生。
你可以在 github 上找到這個專案:
DBHouse 起初的開發目的,是讓使用 AppHouse 架設以及開發自己雲端服務的人,可以很容易存取資料庫。此外,對我們而言更便於管理資料庫資源,面對許多不同的服務,不需要特別為他們開設資料庫權限,亦或是買許多硬體和主機,建立起許多 VM 並做各種安全性規劃。其實,如果把 DBHouse 的用途,想像成 Google 在做的事,就很容易明白:『在 GAE 上你可以使用統一的 Database APIs,存取 Google 提供的資料庫系統(BigTable)。』,同理,我們也是在做同樣的事。
只不過,學 Google 開發自己的一套資料庫太過於困難,不是一個可以達成的目標,所以我們仍然選用 MongoDB 當做 PaaS 的資料庫底層。僅管資料庫不是自己開發的,我們還是可以提供統一的 API,讓開發者存取。統一的 API 有個好處,若能做到當開發者在使用的時候,不需要知道自己在使用什麼資料庫,日後就可以在這 API 之後串接或替換不同的資料庫系統,有很大的彈性可以擴充。
當然,更遠大的目標是希望在一個 Table(Collection) 內,因應不同的欄位需求,而交由不同資料庫處理,更進一步發揮不同資料庫的特色。但是,這夢想遠大,技術上也有很多盲點待討論,所以能不能實現那是另外一回事,至少,短期內在我們的能力範圍和經濟狀況下,暫時無法達成這一步。
雖然 DBHouse 有這樣的初衷和夢一般的計劃,但不代表 DBHouse 一定得和 AppHouse 配合使用,更準確的說,他們本來就是獨立各自發展的專案,各自可獨立運作。說穿了,DBHouse 本身就只是一個 Database API,你可以在 Node.js 裡使用 DBHouse API 去操作自己的 MongoDB(目前只有支援 MongoDB,其他驅動還待開發),也提供了一套 ORM 供開發者使用。
目前 DBHouse 的特色:
目前仍缺少的功能:
使用 NPM 安裝:
展示如何使用 DBHouse 新增一筆資料:
註:『collection()』可使用『table()』替換,兩者功能一樣,只是為了同時符合 SQL 和 NoSQL 的習慣。
如果只是想做簡單的資料庫操作,也可以不使用 ORM 機制:
如果你使用過 MongoDB ,也熟悉傳統 SQL 資料庫,你一定會發現兩者對於 update 的定義相當不一樣,因為在 MongoDB 中預設方法是直接取代掉整筆資料,而傳統 SQL 中只是修改欄位而已。但是在 DBHouse 中,對 update 的處理是採用 SQL 的動作,也就是修改欄位,若是要整筆取代,則另外使用 replace()。
修改 tel 欄位的資料:
既然 Mongo Query Language 是特色,當然可以吃特殊命令,以下程式將把 reviewed 欄位值加一:
後記
大致上來說,DBHouse 已經足夠使用,但真要挑惕的話,還是有很多細節功能待補齊。而目前開發模式,是依照我們手邊專案所需,為其添加新功能,如果遲遲沒有加入您想要的功能,還請見諒。
此外,如果有人喜歡 DBHouse,歡迎投入開發並提交 Patch。:-)
你可以在 github 上找到這個專案:
https://github.com/Mandice/node-dbhouse
DBHouse 起初的開發目的,是讓使用 AppHouse 架設以及開發自己雲端服務的人,可以很容易存取資料庫。此外,對我們而言更便於管理資料庫資源,面對許多不同的服務,不需要特別為他們開設資料庫權限,亦或是買許多硬體和主機,建立起許多 VM 並做各種安全性規劃。其實,如果把 DBHouse 的用途,想像成 Google 在做的事,就很容易明白:『在 GAE 上你可以使用統一的 Database APIs,存取 Google 提供的資料庫系統(BigTable)。』,同理,我們也是在做同樣的事。
只不過,學 Google 開發自己的一套資料庫太過於困難,不是一個可以達成的目標,所以我們仍然選用 MongoDB 當做 PaaS 的資料庫底層。僅管資料庫不是自己開發的,我們還是可以提供統一的 API,讓開發者存取。統一的 API 有個好處,若能做到當開發者在使用的時候,不需要知道自己在使用什麼資料庫,日後就可以在這 API 之後串接或替換不同的資料庫系統,有很大的彈性可以擴充。
當然,更遠大的目標是希望在一個 Table(Collection) 內,因應不同的欄位需求,而交由不同資料庫處理,更進一步發揮不同資料庫的特色。但是,這夢想遠大,技術上也有很多盲點待討論,所以能不能實現那是另外一回事,至少,短期內在我們的能力範圍和經濟狀況下,暫時無法達成這一步。
雖然 DBHouse 有這樣的初衷和夢一般的計劃,但不代表 DBHouse 一定得和 AppHouse 配合使用,更準確的說,他們本來就是獨立各自發展的專案,各自可獨立運作。說穿了,DBHouse 本身就只是一個 Database API,你可以在 Node.js 裡使用 DBHouse API 去操作自己的 MongoDB(目前只有支援 MongoDB,其他驅動還待開發),也提供了一套 ORM 供開發者使用。
目前 DBHouse 的特色:
- 支援簡易的 ORM (包括:多層資料結構)
- 支援 MongoDB v1.6+
- 已實作驅動層以便支援其他資料庫
- 盡可能貼近 SQL 語法習慣(如:select、insert、update、delete、replace)
- 以 Mongo Query Language 為主要查詢語言
- 根據 ORM 設定,自動轉換欄位類型(如:讀寫 MongoDB 時,自動轉換 BinObject)
ex, 讀出 UUID 時轉成字串,以便 JavaScript 操作或網頁間傳遞,存入或查詢時,自動轉成 MongoDB 的 BinObject
目前仍缺少的功能:
- Cursor
- 索引(Index)管理
- 完整的文件
使用 NPM 安裝:
npm install dbhouse
展示如何使用 DBHouse 新增一筆資料:
var DBHouse = require('dbhouse'); var dbHouse = new DBHouse; /* Define schema */ var Address = new DBHouse.Schema({ company: { type: 'String' }, home: { type: 'String' }, updated_time: { type: 'Date' } }); var Contact = new DBHouse.Schema({ _id: { type: 'UUID' }, name: { type: 'String' }, email: { type: 'String' }, tel: { type: 'String' }, created: { type: 'Date' }, address: { type: 'Schema', schema: Address } }); /* Create connection with database server */ dbHouse.connect('mongodb', { host: 'localhost', port: 27017 }, function() { /* Create a database operator */ var db = new DBHouse.Database(dbHouse); db.open('dbhouse') .collection('contact') .model(Contact) .insert({ name: 'Fred Chien', email: 'cfsghost@gmail.com', tel: '0926123456', created: new Date().getTime(), address: { company: 'Taipei', home: 'Taiwan', updated_time: new Date().getTime() } }, function(err, data) { if (err) throw err; console.log(data); }); });
如果只是想做簡單的資料庫操作,也可以不使用 ORM 機制:
var DBHouse = require('dbhouse'); /* Create connection with database server */ var dbHouse = new DBHouse; dbHouse.connect('mongodb', { host: 'localhost', port: 27017 }, function() { /* Create a database operator */ var db = new DBHouse.Database(dbHouse); db.open('dbhouse') .collection('contact') .select({ email: 0 }) .where({ '$or': [ { name: 'Fred Chien'}, { name: 'Stacy Li' } ] }) .limit(1) .query(function(err, data) { if (err) throw err; console.log(data); }); });
如果你使用過 MongoDB ,也熟悉傳統 SQL 資料庫,你一定會發現兩者對於 update 的定義相當不一樣,因為在 MongoDB 中預設方法是直接取代掉整筆資料,而傳統 SQL 中只是修改欄位而已。但是在 DBHouse 中,對 update 的處理是採用 SQL 的動作,也就是修改欄位,若是要整筆取代,則另外使用 replace()。
修改 tel 欄位的資料:
var DBHouse = require('dbhouse'); /* Create connection with database server */ var dbHouse = new DBHouse; dbHouse.connect('mongodb', { host: 'localhost', port: 27017 }, function() { /* Create a database operator */ var db = new DBHouse.Database(dbHouse); db.open('dbhouse') .collection('contact') .where({ name: 'Fred Chien' }) .update({ tel: '0926333572' }, function(err) { if (err) throw err; }); });
既然 Mongo Query Language 是特色,當然可以吃特殊命令,以下程式將把 reviewed 欄位值加一:
var DBHouse = require('dbhouse'); /* Create connection with database server */ var dbHouse = new DBHouse; dbHouse.connect('mongodb', { host: 'localhost', port: 27017 }, function() { /* Create a database operator */ var db = new DBHouse.Database(dbHouse); db.open('dbhouse') .collection('contact') .where({ name: 'Fred Chien' }) .update({ $inc: { reviewed: 1 } }, function(err) { if (err) throw err; }); });
後記
大致上來說,DBHouse 已經足夠使用,但真要挑惕的話,還是有很多細節功能待補齊。而目前開發模式,是依照我們手邊專案所需,為其添加新功能,如果遲遲沒有加入您想要的功能,還請見諒。
此外,如果有人喜歡 DBHouse,歡迎投入開發並提交 Patch。:-)
留言
張貼留言