寫了個模塊,本模塊中應用了sqllite3數據庫,升級原理是檢查數據庫的version版本表中版本值,把版本值加一以後去讀取對應的sql文件,執行sql語句,而後依次循環說取下一個文件直到完成。sql
本模塊中全部sql文件放在/sql/文件夾下,如:contact_create.sql,contact_update_1.sql,contact_update_2.sql,等等,使用時執行 updateUserDB()方法就行。數據庫
var _=require("underscore"); var sqlite3 = require('sqlite3').verbose(); var fs = require('fs'); var async = require("async"); var path=require("path"); EnvironmentDAO = function(){ var DB={},dbNames=["contact","groups","message"];//for example //初始化 var init = function(){ _.each(dbNames,function(name){ DB[name]=new sqlite3.Database(path.join("/main/db",name+'.db'), sqlite3.OPEN_READWRITE | sqlite3.OPEN_CREATE) }); }; init(); // 檢查數據庫是否爲空 this.checkDB = function(db,callback){ db.get("SELECT count(*) as exist FROM sqlite_master WHERE type='table' AND name='version'",function(err,result){ if(err){ console.error("checkDB error",err); callback(null,false); }else{ if(result.exist == 1){ callback(null,true); }else{ callback(null,false); } } }); }; // 通用初始化數據庫 this.initDbCommon = function(db,dbName,callback){ var self=this; var sql = fs.readFileSync('/sql/'+dbName+"_create.sql", 'utf8'); db.exec(sql,function(err,result){ if(err){ console.error("create DB error",dbName,err) } callback&&callback(err,result) }); }; // 通用獲取數據庫版本 this.getDbVersionCommon = function(db,callback){ db.get("SELECT version from version where key = 'db_version'",function(err,result){ if(err){ console.error("getDbVersion err",err); } callback&&callback(err,result); }) }; // 通用升級數據庫 this.updateDbCommon = function(db,dbName,callback){ var self = this; var doUpdate = function(cb){ self.getDbVersionCommon(db,function(err,dbv){ if(err||!dbv){ console.error("getDbVersion err ",dbName,dbv,err); //沒有表或表名錯誤時從新建立表--容錯機制 if(err.code == "SQLITE_ERROR"){ self.initDbCommon(db,dbName,function(err){ if(!err){ self.updateDbCommon(db,dbName,function(err){ if(err){ console.error("second time Init and UPdate DB error",dbName,err); } cb(true); }); } }) }else{ //其它錯誤忽略 cb(false) } }else{ var v = dbv.version; v++; if(fs.existsSync('/sql/'+dbName+"_update_"+v+'.sql')){ var sql = fs.readFileSync('/sql/'+dbName+"_update_"+v+'.sql', 'utf8'); db.exec(sql,function(err){ if(err){ console.error("updateDbCommon err:",dbName,sql,err); cb(false); }else{ cb(true); } }); }else{ cb(false); } } }); } doUpdate(function(tryAgain){ if(tryAgain){ doUpdate.apply(this,[arguments.callee]); }else{ if(typeof callback =="function") callback(); } }); }; // 升級全部用戶數據庫 this.updateUserDB=function(callback){ var self = this; async.forEach( dbNames, function(dbname,cb){ self.checkDB(DB[dbname],function(err,isExist){ if(isExist){ self.updateDbCommon(DB[dbname],dbname,cb); }else{ self.initDbCommon(DB[dbname],dbname,function(){ self.updateDbCommon(DB[dbname],dbname,cb); }) } }) }, function(err){ if(err){ logger.error("updateUserDB Error:",err); } if(typeof callback =="function") { callback(err); } } ); }; } exports = module.exports = new EnvironmentDAO();