欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

用nodejs訪問ActiveX對象,以操作Access數(shù)據(jù)庫為例。

 更新時(shí)間:2011年12月15日 00:25:16   作者:  
有人提問“如果用nodejs訪問sql server?” 找了找資料,發(fā)現(xiàn)有兩類解決方法,使用第三方nodejs插件
起因
有人提問“如果用nodejs訪問sql server?”
找了找資料,發(fā)現(xiàn)有兩類解決方法,使用第三方nodejs插件:https://github.com/orenmazor/node-tds、使用ADODB.ConnectionActiveX對象。
參考:
http://stackoverflow.com/questions/857670/how-to-connect-to-sql-server-database-from-javascript
http://stackoverflow.com/questions/4728385/connecting-to-a-remote-microsoft-sql-server-from-node-js
如果用ActiveX那么在Windows下nodejs將會(huì)無所不能,類似寫asp。那它們怎么通信?得動(dòng)手試試
經(jīng)過
思路
用nodejs通過cscript.exe(windows腳本進(jìn)程)間接訪問ActiveX
cscript能解析jscript和vbscript兩種腳本,無疑為方便維護(hù)選jscript開發(fā)。
參考:http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/cscript_overview.mspx?mfr=true
需解決的問題
1、跨進(jìn)程通信
新版的nodejs里增加了對子進(jìn)程的操作,跨進(jìn)程通信不是問題。
http://nodejs.org/docs/latest/api/all.html#child_Processes
復(fù)制代碼 代碼如下:

var util = require('util'),
exec = require('child_process').exec,
child;


child = exec('cat *.js bad_file | wc -l',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});

如例我們可以拿到控制臺(tái)的輸出內(nèi)容stdout!


2、數(shù)據(jù)庫訪問相關(guān)ActiveX,ADODB.Connection
參考:http://msdn.microsoft.com/en-us/library/windows/desktop/aa746471%28v=vs.85%29.aspx
復(fù)制代碼 代碼如下:

var connection = new ActiveXObject("ADODB.Connection");
var result = 'ok';
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + params.accessfile);
connection.Execute(params.sql);
} catch(ex){
result = ex.message;
}
return {
result: result
};

connection.Open(connectionString),鏈接字符串參數(shù)可以設(shè)置訪問sql server。
參考:http://www.connectionstrings.com/sql-server-2005
3、為方便維護(hù),特別將cscript和nodejs的腳本合并,用typeof exports判斷當(dāng)前運(yùn)行環(huán)境。
4、字符編碼cscript代碼使用ascii編碼
非ascii碼字符進(jìn)行“\uHHHH”Unicode編碼。
5、命令行字符需轉(zhuǎn)義,雙引號(hào)、百分號(hào)在命令行有特殊意義。
參數(shù)傳遞使用base64編碼,避免沖突
cscript環(huán)境MSXML2.DOMDocument可以做base64編解碼
復(fù)制代碼 代碼如下:

function base64Decode(base64){
var xmldom = new ActiveXObject("MSXML2.DOMDocument");
var adostream = new ActiveXObject("ADODB.Stream");
var temp = xmldom.createElement("temp");
temp.dataType = "bin.base64";
temp.text = base64;


adostream.Charset = "utf-8";
adostream.Type = 1; // 1=adTypeBinary 2=adTypeText
adostream.Open();
adostream.Write(temp.nodeTypedValue);
adostream.Position = 0;
adostream.Type = 2; // 1=adTypeBinary 2=adTypeText
var result = adostream.ReadText(-1); // -1=adReadAll
adostream.Close();
adostream = null;
xmldom = null;
return result;
}


總結(jié)
調(diào)用流程
1、創(chuàng)建子進(jìn)程,傳遞經(jīng)過編碼的參數(shù);
2、子進(jìn)程處理完畢將數(shù)據(jù)JSON格式化輸出到控制臺(tái);(子進(jìn)程自動(dòng)結(jié)束)
3、讀取控制臺(tái)的數(shù)據(jù),執(zhí)行回調(diào)函數(shù)。


優(yōu)勢
1、使nodejs擁有訪問ActiveX對象的能力;
2、實(shí)現(xiàn)簡單,開發(fā)維護(hù)方便。


劣勢
1、只能運(yùn)行在Windows平臺(tái);
2、數(shù)據(jù)編解碼會(huì)消耗更多cpu;
3、每次調(diào)用需要?jiǎng)?chuàng)建一個(gè)子進(jìn)程重新連接。(可改進(jìn))
總結(jié)
1、具有一定實(shí)用性;
2、跨進(jìn)程通信性能可繼續(xù)探索。
模塊代碼:
復(fù)制代碼 代碼如下:

var Access = {
create: function(params){
var fso = new ActiveXObject("Scripting.FileSystemObject");
var result = 'ok';
if (!fso.FileExists(params.accessfile)){
var adoxcatalog = new ActiveXObject("ADOX.Catalog");
try {
adoxcatalog.Create("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + params.accessfile);
} catch(ex) {
result = ex.message;
return;
}
adoxcatalog = null;
} else {
result = 'exists';
}
return {
result: result
};
},
existsTable: function(params){
var connection = new ActiveXObject("ADODB.Connection");
var result = 'ok', exists = false;
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + params.accessfile);
var recordset = connection.OpenSchema(20/*adSchemaTables*/);
recordset.MoveFirst();
while (!recordset.EOF){
if (recordset("TABLE_TYPE") == "TABLE" && recordset("TABLE_NAME") == params.tablename){
exists = true;
break;
}
recordset.MoveNext();
}
recordset.Close();
recordset = null;
} catch(ex){
result = ex.message;
}
return {
"result": result,
"exists": exists
};
},
execute: function(params){
var connection = new ActiveXObject("ADODB.Connection");
var result = 'ok';
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + params.accessfile);
connection.Execute(params.sql);
} catch(ex){
result = ex.message;
}
return {
result: result
};
},
query: function(params){
var connection = new ActiveXObject("ADODB.Connection");
var result = 'ok', records = [];
try{
connection.Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + params.accessfile);
var recordset = new ActiveXObject("ADODB.Recordset");
recordset.Open(params.sql, connection);
var fields = [];
var enumer = new Enumerator(recordset.Fields);
for (; !enumer.atEnd(); enumer.moveNext()){
fields.push(enumer.item().name);
}
recordset.MoveFirst();
while (!recordset.EOF) {
var item = {};
for (var i = 0; i < fields.length; i++){
var fieldname = fields[i];
item[fieldname] = recordset(fieldname).value;
}
records.push(item);
recordset.MoveNext();
}
recordset.Close();
recordset = null;
} catch(ex){
result = ex.message;
}
return {
result: result,
records: records
};
}
};
if (/^u/.test(typeof exports)){ // cscript
void function(){
//from http://tangram.baidu.com/api.html#baidu.json
var JSON = {
stringify: (function () {
/**
* 字符串處理時(shí)需要轉(zhuǎn)義的字符表
* @private
*/
var escapeMap = {
"\b": '\\b',
"\t": '\\t',
"\n": '\\n',
"\f": '\\f',
"\r": '\\r',
'"' : '\\"',
"\\": '\\\\'
};
/**
* 字符串序列化
* @private
*/
function encodeString(source) {
if (/["\\\x00-\x1f]/.test(source)) {
source = source.replace(
/["\\\x00-\x1f]/g,
function (match) {
var c = escapeMap[match];
if (c) {
return c;
}
c = match.charCodeAt();
return "\\u00"
+ Math.floor(c / 16).toString(16)
+ (c % 16).toString(16);
});
}
return '"' + source + '"';
}
/**
* 數(shù)組序列化
* @private
*/
function encodeArray(source) {
var result = ["["],
l = source.length,
preComma, i, item;
for (i = 0; i < l; i++) {
item = source[i];
switch (typeof item) {
case "undefined":
case "function":
case "unknown":
break;
default:
if(preComma) {
result.push(',');
}
result.push(JSON.stringify(item));
preComma = 1;
}
}
result.push("]");
return result.join("");
}
/**
* 處理日期序列化時(shí)的補(bǔ)零
* @private
*/
function pad(source) {
return source < 10 ? '0' + source : source;
}
/**
* 日期序列化
* @private
*/
function encodeDate(source){
return '"' + source.getFullYear() + "-"
+ pad(source.getMonth() + 1) + "-"
+ pad(source.getDate()) + "T"
+ pad(source.getHours()) + ":"
+ pad(source.getMinutes()) + ":"
+ pad(source.getSeconds()) + '"';
}
return function (value) {
switch (typeof value) {
case 'undefined':
return 'undefined';
case 'number':
return isFinite(value) ? String(value) : "null";
case 'string':
return encodeString(value).replace(/[^\x00-\xff]/g, function(all) {
return "\\u" + (0x10000 + all.charCodeAt(0)).toString(16).substring(1);
});
case 'boolean':
return String(value);
default:
if (value === null) {
return 'null';
}
if (value instanceof Array) {
return encodeArray(value);
}
if (value instanceof Date) {
return encodeDate(value);
}
var result = ['{'],
encode = JSON.stringify,
preComma,
item;
for (var key in value) {
if (Object.prototype.hasOwnProperty.call(value, key)) {
item = value[key];
switch (typeof item) {
case 'undefined':
case 'unknown':
case 'function':
break;
default:
if (preComma) {
result.push(',');
}
preComma = 1;
result.push(encode(key) + ':' + encode(item));
}
}
}
result.push('}');
return result.join('');
}
};
})(),
parse: function (data) {
return (new Function("return (" + data + ")"))();
}
}
//http://blog.csdn.net/cuixiping/article/details/409468
function base64Decode(base64){
var xmldom = new ActiveXObject("MSXML2.DOMDocument");
var adostream = new ActiveXObject("ADODB.Stream");
var temp = xmldom.createElement("temp");
temp.dataType = "bin.base64";
temp.text = base64;
adostream.Charset = "utf-8";
adostream.Type = 1; // 1=adTypeBinary 2=adTypeText
adostream.Open();
adostream.Write(temp.nodeTypedValue);
adostream.Position = 0;
adostream.Type = 2; // 1=adTypeBinary 2=adTypeText
var result = adostream.ReadText(-1); // -1=adReadAll
adostream.Close();
adostream = null;
xmldom = null;
return result;
}
WScript.StdOut.Write('<json>');
var method = Access[WScript.Arguments(0)];
var result = null;
if (method){
result = method(JSON.parse(base64Decode(WScript.Arguments(1))));
}
WScript.StdOut.Write(JSON.stringify(result));
WScript.StdOut.Write('</json>');
}();
} else { // nodejs
void function(){
function json4stdout(stdout){
if (!stdout) return;
var result = null;
String(stdout).replace(/<json>([\s\S]+)<\/json>/, function(){
result = JSON.parse(arguments[1]);
});
return result;
}
var util = require('util'), exec = require('child_process').exec;
for (var name in Access){
exports[name] = (function(funcname){
return function(params, callback){
console.log([funcname, params]);
exec(
util.format(
'cscript.exe /e:jscript "%s" %s "%s"', __filename,
funcname,
(new Buffer(JSON.stringify(params))).toString('base64')
),
function (error, stdout, stderr) {
if (error != null) {
console.log('exec error: ' + error);
return;
}
console.log('stdout: ' + stdout);
callback && callback(json4stdout(stdout));
}
);
}
})(name);
}
}();
}

調(diào)用代碼:
復(fù)制代碼 代碼如下:

var access = require('./access.js');
var util = require('util');
var accessfile = 'demo.mdb';
access.create({ accessfile: accessfile }, function(data){
console.log(data);
});
access.existsTable({ accessfile: accessfile, tablename: 'demo' }, function(data){
if (data.result == 'ok' && !data.exists){
access.execute({
accessfile: 'demo.mdb',
sql: "CREATE TABLE demo(id Counter Primary key, data Text(100))"
});
}
});
access.execute({
accessfile: 'demo.mdb',
sql: util.format("INSERT INTO demo(data) VALUES('zswang 路過!%s')", +new Date)
}, function(data){
console.log(data);
});
access.query({
accessfile: 'demo.mdb',
sql: "SELECT * FROM demo"
}, function(data){
console.log(data);
});

最新代碼:http://code.google.com/p/nodejs-demo/source/browse/#svn%2Ftrunk%2Fdatabase

相關(guān)文章

  • JavaScript代碼簡化技巧實(shí)例解析

    JavaScript代碼簡化技巧實(shí)例解析

    這篇文章主要介紹了JavaScript代碼簡化技巧實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • JS繼承實(shí)現(xiàn)方法及優(yōu)缺點(diǎn)詳解

    JS繼承實(shí)現(xiàn)方法及優(yōu)缺點(diǎn)詳解

    這篇文章主要介紹了JS繼承實(shí)現(xiàn)方法及優(yōu)缺點(diǎn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Vue考試系統(tǒng)的后臺(tái)管理功能開發(fā)示例解讀

    Vue考試系統(tǒng)的后臺(tái)管理功能開發(fā)示例解讀

    這篇文章主要介紹了Vue考試系統(tǒng)后臺(tái)管理項(xiàng)目的登錄、記住密碼功能具體實(shí)現(xiàn)流程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-09-09
  • js實(shí)現(xiàn)addClass,removeClass,hasClass的函數(shù)代碼

    js實(shí)現(xiàn)addClass,removeClass,hasClass的函數(shù)代碼

    js實(shí)現(xiàn)addClass,removeClass,hasClass的函數(shù)代碼,需要的朋友可以參考下。
    2011-07-07
  • 原生js封裝的ajax方法示例

    原生js封裝的ajax方法示例

    這篇文章主要介紹了原生js封裝的ajax方法,結(jié)合實(shí)例形式分析了JavaScript封裝ajax操作及調(diào)用方法相關(guān)操作技巧,非常簡單實(shí)用,需要的朋友可以參考下
    2018-08-08
  • 判斷腳本加載是否完成的方法

    判斷腳本加載是否完成的方法

    在“按需加載”的需求中,我們經(jīng)常會(huì)判斷當(dāng)腳本加載完成時(shí),返回一個(gè)回調(diào)函數(shù),那如何去判斷腳本的加載完成呢?
    2009-05-05
  • js自定義trim函數(shù)實(shí)現(xiàn)刪除兩端空格功能

    js自定義trim函數(shù)實(shí)現(xiàn)刪除兩端空格功能

    這篇文章主要介紹了js自定義trim函數(shù)實(shí)現(xiàn)刪除兩端空格功能,結(jié)合實(shí)例形式分析了javascript基于正則替換實(shí)現(xiàn)類似trim函數(shù)刪除字符串兩端空格的相關(guān)操作技巧,并附帶jQuery類似功能函數(shù)使用方法,需要的朋友可以參考下
    2018-02-02
  • elementUI 設(shè)置input的只讀或禁用的方法

    elementUI 設(shè)置input的只讀或禁用的方法

    這篇文章主要介紹了elementUI 設(shè)置input的只讀或禁用的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-10-10
  • JavaScript常用代碼書寫規(guī)范的超全面總結(jié)

    JavaScript常用代碼書寫規(guī)范的超全面總結(jié)

    這篇文章給大家全面總結(jié)了JavaScript常用代碼的書寫規(guī)范,分別利用推薦和不推薦的兩種示例代碼讓大家更能直接的了解書寫規(guī)范,其實(shí)關(guān)于javascript代碼規(guī)范我們應(yīng)該遵循古老的原則:“能做并不意味著應(yīng)該做”,好了,下面我們就來一起看看吧。
    2016-09-09
  • 使用js完成節(jié)點(diǎn)的增刪改復(fù)制等的操作

    使用js完成節(jié)點(diǎn)的增刪改復(fù)制等的操作

    本文為大家詳細(xì)介紹下使用js完成節(jié)點(diǎn)的增刪改復(fù)制等的操作,具體的實(shí)現(xiàn)如下,感興趣的朋友可以參考下
    2014-01-01

最新評(píng)論