Comparing version 0.3.4 to 0.4.0
@@ -0,1 +1,9 @@ | ||
v0.4.0 (2013-12-12) | ||
------------------- | ||
[new] Added support for transactions. | ||
[new] node-tds is now available as an optional TDS driver. | ||
[new] Documentation updated to CSDoc spec. | ||
[change] Tedious driver no longer use tedious-connection-pool for connection pooling | ||
[change] Msnodesql is now pooled | ||
v0.3.4 (2013-10-23) | ||
@@ -2,0 +10,0 @@ ------------------- |
@@ -1,2 +0,2 @@ | ||
// Generated by CoffeeScript 1.6.2 | ||
// Generated by CoffeeScript 1.6.3 | ||
(function() { | ||
@@ -3,0 +3,0 @@ var TYPES, key, value; |
454
lib/main.js
@@ -1,4 +0,4 @@ | ||
// Generated by CoffeeScript 1.6.2 | ||
// Generated by CoffeeScript 1.6.3 | ||
(function() { | ||
var Connection, Request, TYPES, events, getTypeByValue, global_connection, key, map, util, value; | ||
var Connection, Request, TYPES, Transaction, events, getTypeByValue, global_connection, key, map, util, value; | ||
@@ -15,5 +15,22 @@ events = require('events'); | ||
/* | ||
Register you own type map. | ||
**Example:** | ||
``` | ||
sql.map.register(MyClass, sql.Text); | ||
``` | ||
You can also overwrite default type map. | ||
``` | ||
sql.map.register(Number, sql.BigInt); | ||
``` | ||
@path module.exports.map | ||
@param {*} jstype JS data type. | ||
@param {*} sqltype SQL data type. | ||
*/ | ||
map.register = function(jstype, sqltype) { | ||
var index, item, _i, _len; | ||
for (index = _i = 0, _len = this.length; _i < _len; index = ++_i) { | ||
@@ -27,6 +44,7 @@ item = this[index]; | ||
} | ||
return this.push({ | ||
this.push({ | ||
js: jstype, | ||
sql: sqltype | ||
}); | ||
return null; | ||
}; | ||
@@ -42,5 +60,9 @@ | ||
/* | ||
@ignore | ||
*/ | ||
getTypeByValue = function(value) { | ||
var item, _i, _j, _k, _l, _len, _len1, _len2, _len3; | ||
if (value === null || value === void 0) { | ||
@@ -87,2 +109,11 @@ return TYPES.VarChar; | ||
/* | ||
Class Connection. | ||
@property {Boolean} connected If true, connection is established. | ||
@property {Boolean} connecting If true, connection is being established. | ||
@property {*} driver Reference to configured Driver. | ||
*/ | ||
Connection = (function() { | ||
@@ -95,16 +126,26 @@ Connection.prototype.connected = false; | ||
/* | ||
Create new Connection. | ||
@param {Object} config Connection configuration. | ||
@callback callback A callback which is called after connection has established, or an error has occurred. | ||
@param {Error} err Error on error, otherwise null. | ||
*/ | ||
function Connection(config, callback) { | ||
var err, _base, _base1, _ref, _ref1; | ||
var err, _base, _base1; | ||
this.config = config; | ||
if ((_ref = (_base = this.config).driver) == null) { | ||
if ((_base = this.config).driver == null) { | ||
_base.driver = 'tedious'; | ||
} | ||
if ((_ref1 = (_base1 = this.config).port) == null) { | ||
if ((_base1 = this.config).port == null) { | ||
_base1.port = 1433; | ||
} | ||
if (this.config.driver === 'tedious') { | ||
this.driver = require('./tedious')(Connection, Request); | ||
this.driver = require('./tedious')(Connection, Transaction, Request); | ||
} else if (this.config.driver === 'msnodesql') { | ||
this.driver = require('./msnodesql')(Connection, Request); | ||
this.driver = require('./msnodesql')(Connection, Transaction, Request); | ||
} else if (this.config.driver === 'tds') { | ||
this.driver = require('./tds')(Connection, Transaction, Request); | ||
} else { | ||
@@ -123,6 +164,15 @@ err = new Error("Unknown driver " + this.config.driver + "!"); | ||
/* | ||
Create connection to the server. | ||
@callback callback A callback which is called after connection has established, or an error has occurred. | ||
@param {Error} err Error on error, otherwise null. | ||
@returns {Connection} | ||
*/ | ||
Connection.prototype.connect = function(callback) { | ||
var err, | ||
_this = this; | ||
if (this.connected) { | ||
@@ -145,3 +195,3 @@ err = new Error("Database is already connected! Call close before connecting to different database."); | ||
this.connecting = true; | ||
return this.driver.connection.prototype.connect.call(this, this.config, function(err) { | ||
this.driver.connection.prototype.connect.call(this, this.config, function(err) { | ||
if (!_this.connecting) { | ||
@@ -156,4 +206,12 @@ return; | ||
}); | ||
return this; | ||
}; | ||
/* | ||
Close connection to the server. | ||
@returns {Connection} | ||
*/ | ||
Connection.prototype.close = function() { | ||
@@ -163,10 +221,18 @@ if (this.connecting) { | ||
this.driver.connection.prototype.close.call(this); | ||
return this.driver = null; | ||
this.driver = null; | ||
} else if (this.connected) { | ||
this.connected = false; | ||
this.driver.connection.prototype.close.call(this); | ||
return this.driver = null; | ||
this.driver = null; | ||
} | ||
return this; | ||
}; | ||
/* | ||
Returns new request using this connection. | ||
@returns {Request} | ||
*/ | ||
Connection.prototype.request = function() { | ||
@@ -176,2 +242,13 @@ return new Request(this); | ||
/* | ||
Returns new transaction using this connection. | ||
@returns {Transaction} | ||
*/ | ||
Connection.prototype.transaction = function() { | ||
return new Transaction(this); | ||
}; | ||
return Connection; | ||
@@ -181,5 +258,153 @@ | ||
/* | ||
Class Transaction. | ||
@property {Connection} connection Reference to used connection. | ||
*/ | ||
Transaction = (function() { | ||
Transaction.prototype._pooledConnection = null; | ||
Transaction.prototype._queue = null; | ||
Transaction.prototype._working = false; | ||
/* | ||
Create new Transaction. | ||
@param {Connection} connection If ommited, global connection is used instead. | ||
*/ | ||
function Transaction(connection) { | ||
this.connection = connection != null ? connection : global_connection; | ||
this._queue = []; | ||
} | ||
/* | ||
Begin a transaction. | ||
@callback callback A callback which is called after transaction has began, or an error has occurred. | ||
@param {Error} err Error on error, otherwise null. | ||
@returns {Transaction} | ||
*/ | ||
Transaction.prototype.begin = function(callback) { | ||
if (this._pooledConnection) { | ||
callback(new Error("Transaction is already running.")); | ||
return this; | ||
} | ||
this.connection.driver.transaction.prototype.begin.call(this, callback); | ||
return this; | ||
}; | ||
/* | ||
Commit a transaction. | ||
@callback callback A callback which is called after transaction has commited, or an error has occurred. | ||
@param {Error} err Error on error, otherwise null. | ||
@returns {Transaction} | ||
*/ | ||
Transaction.prototype.commit = function(callback) { | ||
if (!this._pooledConnection) { | ||
callback(new Error("Transaction has not started. Call begin() first.")); | ||
return this; | ||
} | ||
this.connection.driver.transaction.prototype.commit.call(this, callback); | ||
return this; | ||
}; | ||
/* | ||
Execute next request in queue. | ||
@private | ||
@returns {Transaction} | ||
*/ | ||
Transaction.prototype.next = function() { | ||
if (this._queue.length) { | ||
return this._queue.shift()(null, this._pooledConnection); | ||
} else { | ||
return this._working = false; | ||
} | ||
}; | ||
/* | ||
Add request to queue for connection. If queue is empty, execute the request immediately. | ||
@private | ||
@callback callback A callback to call when connection in ready to execute request. | ||
@param {Error} err Error on error, otherwise null. | ||
@param {*} conn Internal driver's connection. | ||
@returns {Transaction} | ||
*/ | ||
Transaction.prototype.queue = function(callback) { | ||
if (!this._pooledConnection) { | ||
callback(new Error("Transaction has not started. Call begin() first.")); | ||
return this; | ||
} | ||
if (this._working) { | ||
return this._queue.push(callback); | ||
} else { | ||
this._working = true; | ||
return callback(null, this._pooledConnection); | ||
} | ||
}; | ||
/* | ||
Returns new request using this transaction. | ||
@returns {Request} | ||
*/ | ||
Transaction.prototype.request = function() { | ||
return new Request(this); | ||
}; | ||
/* | ||
Rollback a transaction. | ||
@callback callback A callback which is called after transaction has rolled back, or an error has occurred. | ||
@param {Error} err Error on error, otherwise null. | ||
@returns {Transaction} | ||
*/ | ||
Transaction.prototype.rollback = function(callback) { | ||
if (!this._pooledConnection) { | ||
callback(new Error("Transaction has not started. Call begin() first.")); | ||
return this; | ||
} | ||
this.connection.driver.transaction.prototype.rollback.call(this, callback); | ||
return this; | ||
}; | ||
return Transaction; | ||
})(); | ||
/* | ||
Class Request. | ||
@property {Connection} connection Reference to used connection. | ||
@property {Transaction} transaction Reference to transaction when request was created in transaction. | ||
@property {*} parameters Collection of input and output parameters. | ||
@property {Boolean} verbose If `true`, debug messages are printed to message log. | ||
@property {Boolean} multiple If `true`, `query` will handle multiple recordsets (`execute` always expect multiple recordsets). | ||
*/ | ||
Request = (function() { | ||
Request.prototype.connection = null; | ||
Request.prototype.transaction = null; | ||
Request.prototype.parameters = null; | ||
@@ -191,15 +416,56 @@ | ||
/* | ||
Create new Request. | ||
@param {Connection} connection If ommited, global connection is used instead. | ||
*/ | ||
function Request(connection) { | ||
this.connection = connection != null ? connection : global_connection; | ||
if (connection instanceof Transaction) { | ||
this.transaction = connection; | ||
this.connection = connection.connection; | ||
} else if (connection instanceof Connection) { | ||
this.connection = connection; | ||
} else { | ||
this.connection = global_connection; | ||
} | ||
this.parameters = {}; | ||
} | ||
/* | ||
Acquire connection for this request from connection. | ||
*/ | ||
Request.prototype._acquire = function(callback) { | ||
return this.connection.driver.request.prototype._acquire.call(this, callback); | ||
}; | ||
/* | ||
Release connection used by this request. | ||
*/ | ||
Request.prototype._release = function(connection) { | ||
return this.connection.driver.request.prototype._release.call(this, connection); | ||
}; | ||
/* | ||
Add an input parameter to the request. | ||
**Example:** | ||
``` | ||
request.input('input_parameter', value); | ||
request.input('input_parameter', sql.Int, value); | ||
``` | ||
@param {String} name Name of the input parameter without @ char. | ||
@param {*} [type] SQL data type of input parameter. If you omit type, module automaticaly decide which SQL data type should be used based on JS data type. | ||
@param {*} value Input parameter value. `undefined` and `NaN` values are automatically converted to `null` values. | ||
@returns {Request} | ||
*/ | ||
Request.prototype.input = function(name, type, value) { | ||
/* | ||
Append new input parameter to current request. | ||
Usage: | ||
request.append name, value | ||
request.append name, type, value | ||
*/ | ||
if (arguments.length === 1) { | ||
@@ -220,3 +486,3 @@ throw new Error("Invalid number of arguments. At least 2 arguments expected."); | ||
} | ||
return this.parameters[name] = { | ||
this.parameters[name] = { | ||
name: name, | ||
@@ -227,15 +493,24 @@ type: type, | ||
}; | ||
return this; | ||
}; | ||
/* | ||
Add an output parameter to the request. | ||
**Example:** | ||
``` | ||
request.output('output_parameter', sql.Int); | ||
``` | ||
@param {String} name Name of the output parameter without @ char. | ||
@param {*} type SQL data type of output parameter. | ||
@returns {Request} | ||
*/ | ||
Request.prototype.output = function(name, type) { | ||
/* | ||
Append new output parameter to current request. | ||
Usage: | ||
request.append name, type | ||
*/ | ||
if (!type) { | ||
type = tds.TYPES.VarChar; | ||
} | ||
return this.parameters[name] = { | ||
this.parameters[name] = { | ||
name: name, | ||
@@ -245,8 +520,42 @@ type: type, | ||
}; | ||
return this; | ||
}; | ||
/* | ||
Execute the SQL command. | ||
**Example:** | ||
``` | ||
var request = new sql.Request(); | ||
request.query('select 1 as number', function(err, recordset) { | ||
console.log(recordset[0].number); // return 1 | ||
// ... | ||
}); | ||
``` | ||
You can enable multiple recordsets in querries by `request.multiple = true` command. | ||
``` | ||
var request = new sql.Request(); | ||
request.multiple = true; | ||
request.query('select 1 as number; select 2 as number', function(err, recordsets) { | ||
console.log(recordsets[0][0].number); // return 1 | ||
console.log(recordsets[1][0].number); // return 2 | ||
// ... | ||
}); | ||
``` | ||
@param {String} command T-SQL command to be executed. | ||
@callback callback A callback which is called after execution has completed, or an error has occurred. | ||
@param {Error} err Error on error, otherwise null. | ||
@param {*} recordset Recordset. | ||
@returns {Request} | ||
*/ | ||
Request.prototype.query = function(command, callback) { | ||
/* | ||
Execute specified sql command. | ||
*/ | ||
if (!this.connection) { | ||
@@ -257,9 +566,36 @@ return process.nextTick(function() { | ||
} | ||
return this.connection.driver.request.prototype.query.call(this, command, callback); | ||
this.connection.driver.request.prototype.query.call(this, command, callback); | ||
return this; | ||
}; | ||
/* | ||
Call a stored procedure. | ||
**Example:** | ||
``` | ||
var request = new sql.Request(); | ||
request.input('input_parameter', sql.Int, value); | ||
request.output('output_parameter', sql.Int); | ||
request.execute('procedure_name', function(err, recordsets, returnValue) { | ||
console.log(recordsets.length); // count of recordsets returned by procedure | ||
console.log(recordset[0].length); // count of rows contained in first recordset | ||
console.log(returnValue); // procedure return value | ||
console.log(request.parameters.output_parameter.value); // output value | ||
// ... | ||
}); | ||
``` | ||
@param {String} procedure Name of the stored procedure to be executed. | ||
@callback callback A callback which is called after execution has completed, or an error has occurred. | ||
@param {Error} err Error on error, otherwise null. | ||
@param {*} recordset Recordset. | ||
@param {Number} returnValue Procedure return value. | ||
@returns {Request} | ||
*/ | ||
Request.prototype.execute = function(procedure, callback) { | ||
/* | ||
Execute stored procedure with specified parameters. | ||
*/ | ||
if (!this.connection) { | ||
@@ -270,5 +606,18 @@ return process.nextTick(function() { | ||
} | ||
return this.connection.driver.request.prototype.execute.call(this, procedure, callback); | ||
this.connection.driver.request.prototype.execute.call(this, procedure, callback); | ||
return this; | ||
}; | ||
/* | ||
Cancel currently executed request. | ||
@returns {Request} | ||
*/ | ||
Request.prototype.cancel = function() { | ||
this.connection.driver.request.prototype.cancel.call(this); | ||
return this; | ||
}; | ||
return Request; | ||
@@ -278,2 +627,13 @@ | ||
/* | ||
Open global connection. | ||
@param {Object} config Connection configuration. | ||
@callback callback A callback which is called after connection has established, or an error has occurred. | ||
@param {Error} err Error on error, otherwise null. | ||
@returns {Connection} | ||
*/ | ||
module.exports.connect = function(config, callback) { | ||
@@ -284,2 +644,9 @@ global_connection = new Connection(config); | ||
/* | ||
Close global connection. | ||
@returns {Connection} | ||
*/ | ||
module.exports.close = function() { | ||
@@ -291,2 +658,4 @@ return global_connection != null ? global_connection.close() : void 0; | ||
module.exports.Transaction = Transaction; | ||
module.exports.Request = Request; | ||
@@ -316,2 +685,9 @@ | ||
/* | ||
Initialize Tedious connection pool. | ||
@deprecated | ||
*/ | ||
module.exports.init = function() { | ||
@@ -318,0 +694,0 @@ return module.exports.connect({ |
@@ -1,7 +0,9 @@ | ||
// Generated by CoffeeScript 1.6.2 | ||
// Generated by CoffeeScript 1.6.3 | ||
(function() { | ||
var DECLARATIONS, TYPES, castParameter, createColumns, msnodesql, typeDeclaration, util, | ||
var DECLARATIONS, Pool, TYPES, castParameter, createColumns, msnodesql, typeDeclaration, util, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
Pool = require('generic-pool').Pool; | ||
msnodesql = require('msnodesql'); | ||
@@ -15,2 +17,7 @@ | ||
/* | ||
@ignore | ||
*/ | ||
castParameter = function(value, type) { | ||
@@ -76,5 +83,9 @@ switch (type) { | ||
/* | ||
@ignore | ||
*/ | ||
createColumns = function(meta) { | ||
var out, value, _i, _len; | ||
out = {}; | ||
@@ -92,2 +103,7 @@ for (_i = 0, _len = meta.length; _i < _len; _i++) { | ||
/* | ||
@ignore | ||
*/ | ||
typeDeclaration = function(type) { | ||
@@ -108,5 +124,9 @@ switch (type) { | ||
module.exports = function(Connection, Request) { | ||
var MsnodesqlConnection, MsnodesqlRequest, _ref, _ref1; | ||
/* | ||
@ignore | ||
*/ | ||
module.exports = function(Connection, Transaction, Request) { | ||
var MsnodesqlConnection, MsnodesqlRequest, MsnodesqlTransaction, _ref, _ref1, _ref2; | ||
MsnodesqlConnection = (function(_super) { | ||
@@ -120,40 +140,107 @@ __extends(MsnodesqlConnection, _super); | ||
MsnodesqlConnection.prototype["native"] = null; | ||
MsnodesqlConnection.prototype.pool = null; | ||
MsnodesqlConnection.prototype.connect = function(config, callback) { | ||
var connectionString, _ref1, | ||
var cfg, cfg_pool, key, value, _ref1, _ref2, | ||
_this = this; | ||
if ((_ref1 = config.connectionString) == null) { | ||
config.connectionString = 'Driver={SQL Server Native Client 11.0};Server=#{server},#{port};Database=#{database};Uid=#{user};Pwd=#{password};'; | ||
} | ||
connectionString = config.connectionString.replace(new RegExp('#{([^}]*)}', 'g'), function(p) { | ||
cfg = { | ||
connectionString: (_ref1 = config.connectionString) != null ? _ref1 : 'Driver={SQL Server Native Client 11.0};Server=#{server},#{port};Database=#{database};Uid=#{user};Pwd=#{password};' | ||
}; | ||
cfg.connectionString = cfg.connectionString.replace(new RegExp('#{([^}]*)}', 'g'), function(p) { | ||
var _ref2; | ||
return (_ref2 = config[p.substr(2, p.length - 3)]) != null ? _ref2 : ''; | ||
}); | ||
return msnodesql.open(connectionString, function(err, conn) { | ||
cfg_pool = { | ||
name: 'mssql', | ||
max: 10, | ||
min: 0, | ||
idleTimeoutMillis: 30000, | ||
create: function(callback) { | ||
return msnodesql.open(cfg.connectionString, function(err, c) { | ||
if (err) { | ||
return callback(err, null); | ||
} | ||
return callback(null, c); | ||
}); | ||
}, | ||
destroy: function(c) { | ||
return c.close(); | ||
} | ||
}; | ||
if (config.pool) { | ||
_ref2 = config.pool; | ||
for (key in _ref2) { | ||
value = _ref2[key]; | ||
cfg_pool[key] = value; | ||
} | ||
} | ||
this.pool = Pool(cfg_pool, cfg); | ||
return this.pool.acquire(function(err, connection) { | ||
if (err && !(err instanceof Error)) { | ||
err = new Error(err); | ||
} | ||
_this.pool.release(connection); | ||
return typeof callback === "function" ? callback(err) : void 0; | ||
}); | ||
}; | ||
MsnodesqlConnection.prototype.close = function(callback) { | ||
var _ref1, | ||
_this = this; | ||
return (_ref1 = this.pool) != null ? _ref1.drain(function() { | ||
_this.pool.destroyAllNow(); | ||
_this.pool = null; | ||
return typeof callback === "function" ? callback(null) : void 0; | ||
}) : void 0; | ||
}; | ||
return MsnodesqlConnection; | ||
})(Connection); | ||
MsnodesqlTransaction = (function(_super) { | ||
__extends(MsnodesqlTransaction, _super); | ||
function MsnodesqlTransaction() { | ||
_ref1 = MsnodesqlTransaction.__super__.constructor.apply(this, arguments); | ||
return _ref1; | ||
} | ||
MsnodesqlTransaction.prototype.begin = function(callback) { | ||
var _this = this; | ||
return this.connection.pool.acquire(function(err, connection) { | ||
var req; | ||
if (err) { | ||
return callback(err); | ||
} | ||
_this["native"] = conn; | ||
return typeof callback === "function" ? callback(null) : void 0; | ||
_this._pooledConnection = connection; | ||
req = _this.request(); | ||
return req.query('begin tran', callback); | ||
}); | ||
}; | ||
MsnodesqlConnection.prototype.close = function(callback) { | ||
var _ref1; | ||
MsnodesqlTransaction.prototype.commit = function(callback) { | ||
var req, | ||
_this = this; | ||
req = this.request(); | ||
return req.query('commit tran', function(err) { | ||
_this.connection.pool.release(_this._pooledConnection); | ||
_this._pooledConnection = null; | ||
return callback(err); | ||
}); | ||
}; | ||
if ((_ref1 = this["native"]) != null) { | ||
_ref1.close(); | ||
} | ||
this["native"] = null; | ||
return process.nextTick(function() { | ||
return typeof callback === "function" ? callback(null) : void 0; | ||
MsnodesqlTransaction.prototype.rollback = function(callback) { | ||
var req, | ||
_this = this; | ||
req = this.request(); | ||
return req.query('rollback tran', function(err) { | ||
_this.connection.pool.release(_this._pooledConnection); | ||
_this._pooledConnection = null; | ||
return callback(err); | ||
}); | ||
}; | ||
return MsnodesqlConnection; | ||
return MsnodesqlTransaction; | ||
})(Connection); | ||
})(Transaction); | ||
MsnodesqlRequest = (function(_super) { | ||
@@ -163,4 +250,4 @@ __extends(MsnodesqlRequest, _super); | ||
function MsnodesqlRequest() { | ||
_ref1 = MsnodesqlRequest.__super__.constructor.apply(this, arguments); | ||
return _ref1; | ||
_ref2 = MsnodesqlRequest.__super__.constructor.apply(this, arguments); | ||
return _ref2; | ||
} | ||
@@ -170,6 +257,21 @@ | ||
MsnodesqlRequest.prototype._acquire = function(callback) { | ||
if (this.transaction) { | ||
return this.transaction.queue(callback); | ||
} else { | ||
return this.connection.pool.acquire(callback); | ||
} | ||
}; | ||
MsnodesqlRequest.prototype._release = function(connection) { | ||
if (this.transaction) { | ||
return this.transaction.next(); | ||
} else { | ||
return this.connection.pool.release(connection); | ||
} | ||
}; | ||
MsnodesqlRequest.prototype.query = function(command, callback) { | ||
var columns, handleOutput, input, name, output, param, recordset, recordsets, req, row, sets, started, | ||
var columns, handleOutput, input, name, output, param, recordset, recordsets, row, sets, started, | ||
_this = this; | ||
if (this.verbose && !this.nested) { | ||
@@ -181,3 +283,2 @@ console.log("---------- sql query ----------\n query: " + command); | ||
var elapsed; | ||
if (this.verbose && !this.nested) { | ||
@@ -200,8 +301,7 @@ console.log("---------- response -----------"); | ||
input = (function() { | ||
var _ref2, _results; | ||
_ref2 = this.parameters; | ||
var _ref3, _results; | ||
_ref3 = this.parameters; | ||
_results = []; | ||
for (name in _ref2) { | ||
param = _ref2[name]; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
_results.push("@" + param.name + " " + (typeDeclaration(param.type))); | ||
@@ -212,8 +312,7 @@ } | ||
sets = (function() { | ||
var _ref2, _results; | ||
_ref2 = this.parameters; | ||
var _ref3, _results; | ||
_ref3 = this.parameters; | ||
_results = []; | ||
for (name in _ref2) { | ||
param = _ref2[name]; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
if (param.io === 1) { | ||
@@ -226,8 +325,7 @@ _results.push("set @" + param.name + "=?"); | ||
output = (function() { | ||
var _ref2, _results; | ||
_ref2 = this.parameters; | ||
var _ref3, _results; | ||
_ref3 = this.parameters; | ||
_results = []; | ||
for (name in _ref2) { | ||
param = _ref2[name]; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
if (param.io === 2) { | ||
@@ -247,96 +345,103 @@ _results.push("@" + param.name + " as '" + param.name + "'"); | ||
} | ||
req = this.connection["native"].queryRaw(command, (function() { | ||
var _ref2, _results; | ||
_ref2 = this.parameters; | ||
_results = []; | ||
for (name in _ref2) { | ||
param = _ref2[name]; | ||
if (param.io === 1) { | ||
_results.push(castParameter(param.value, param.type)); | ||
return this._acquire(function(err, connection) { | ||
var req; | ||
if (!err) { | ||
req = connection.queryRaw(command, (function() { | ||
var _ref3, _results; | ||
_ref3 = this.parameters; | ||
_results = []; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
if (param.io === 1) { | ||
_results.push(castParameter(param.value, param.type)); | ||
} | ||
} | ||
return _results; | ||
}).call(_this)); | ||
if (_this.verbose && !_this.nested) { | ||
console.log("---------- response -----------"); | ||
} | ||
} | ||
return _results; | ||
}).call(this)); | ||
if (this.verbose && !this.nested) { | ||
console.log("---------- response -----------"); | ||
} | ||
req.on('meta', function(metadata) { | ||
if (row && _this.verbose) { | ||
console.log(util.inspect(row)); | ||
console.log("---------- --------------------"); | ||
} | ||
row = null; | ||
columns = metadata; | ||
recordset = []; | ||
Object.defineProperty(recordset, 'columns', { | ||
enumerable: false, | ||
value: createColumns(metadata) | ||
}); | ||
return recordsets.push(recordset); | ||
}); | ||
req.on('row', function(rownumber) { | ||
if (row && _this.verbose) { | ||
console.log(util.inspect(row)); | ||
console.log("---------- --------------------"); | ||
} | ||
row = {}; | ||
return recordset.push(row); | ||
}); | ||
req.on('column', function(idx, data, more) { | ||
var exi; | ||
exi = row[columns[idx].name]; | ||
if (exi != null) { | ||
if (exi instanceof Array) { | ||
return exi.push(data); | ||
} else { | ||
return row[columns[idx].name] = [exi, data]; | ||
} | ||
} else { | ||
return row[columns[idx].name] = data; | ||
} | ||
}); | ||
req.once('error', function(err) { | ||
var elapsed; | ||
if (_this.verbose && !_this.nested) { | ||
elapsed = Date.now() - started; | ||
console.log(" error: " + err); | ||
console.log(" duration: " + elapsed + "ms"); | ||
console.log("---------- completed ----------"); | ||
} | ||
return typeof callback === "function" ? callback(err) : void 0; | ||
}); | ||
return req.once('done', function() { | ||
var elapsed, last, _ref2, _ref3; | ||
if (!_this.nested) { | ||
if (_this.verbose) { | ||
if (row) { | ||
req.on('meta', function(metadata) { | ||
if (row && _this.verbose) { | ||
console.log(util.inspect(row)); | ||
console.log("---------- --------------------"); | ||
} | ||
} | ||
if (handleOutput) { | ||
last = (_ref2 = recordsets.pop()) != null ? _ref2[0] : void 0; | ||
_ref3 = _this.parameters; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
if (!(param.io === 2)) { | ||
continue; | ||
row = null; | ||
columns = metadata; | ||
recordset = []; | ||
Object.defineProperty(recordset, 'columns', { | ||
enumerable: false, | ||
value: createColumns(metadata) | ||
}); | ||
return recordsets.push(recordset); | ||
}); | ||
req.on('row', function(rownumber) { | ||
if (row && _this.verbose) { | ||
console.log(util.inspect(row)); | ||
console.log("---------- --------------------"); | ||
} | ||
row = {}; | ||
return recordset.push(row); | ||
}); | ||
req.on('column', function(idx, data, more) { | ||
var exi; | ||
exi = row[columns[idx].name]; | ||
if (exi != null) { | ||
if (exi instanceof Array) { | ||
return exi.push(data); | ||
} else { | ||
return row[columns[idx].name] = [exi, data]; | ||
} | ||
param.value = last[param.name]; | ||
} else { | ||
return row[columns[idx].name] = data; | ||
} | ||
}); | ||
req.once('error', function(err) { | ||
var elapsed; | ||
if (_this.verbose && !_this.nested) { | ||
elapsed = Date.now() - started; | ||
console.log(" error: " + err); | ||
console.log(" duration: " + elapsed + "ms"); | ||
console.log("---------- completed ----------"); | ||
} | ||
return typeof callback === "function" ? callback(err) : void 0; | ||
}); | ||
return req.once('done', function() { | ||
var elapsed, last, _ref3, _ref4; | ||
if (!_this.nested) { | ||
if (_this.verbose) { | ||
console.log(" output: @" + param.name + ", " + param.type.name + ", " + param.value); | ||
if (row) { | ||
console.log(util.inspect(row)); | ||
console.log("---------- --------------------"); | ||
} | ||
} | ||
if (handleOutput) { | ||
last = (_ref3 = recordsets.pop()) != null ? _ref3[0] : void 0; | ||
_ref4 = _this.parameters; | ||
for (name in _ref4) { | ||
param = _ref4[name]; | ||
if (!(param.io === 2)) { | ||
continue; | ||
} | ||
param.value = last[param.name]; | ||
if (_this.verbose) { | ||
console.log(" output: @" + param.name + ", " + param.type.name + ", " + param.value); | ||
} | ||
} | ||
} | ||
if (_this.verbose) { | ||
elapsed = Date.now() - started; | ||
console.log(" duration: " + elapsed + "ms"); | ||
console.log("---------- completed ----------"); | ||
} | ||
} | ||
_this._release(connection); | ||
return typeof callback === "function" ? callback(null, _this.multiple || _this.nested ? recordsets : recordsets[0]) : void 0; | ||
}); | ||
} else { | ||
if (connection) { | ||
_this._release(connection); | ||
} | ||
if (_this.verbose) { | ||
elapsed = Date.now() - started; | ||
console.log(" duration: " + elapsed + "ms"); | ||
console.log("---------- completed ----------"); | ||
} | ||
return typeof callback === "function" ? callback(err) : void 0; | ||
} | ||
return typeof callback === "function" ? callback(null, _this.multiple || _this.nested ? recordsets : recordsets[0]) : void 0; | ||
}); | ||
@@ -346,5 +451,4 @@ }; | ||
MsnodesqlRequest.prototype.execute = function(procedure, callback) { | ||
var cmd, name, param, spp, started, _ref2, | ||
var cmd, name, param, spp, started, _ref3, | ||
_this = this; | ||
if (this.verbose) { | ||
@@ -355,8 +459,7 @@ console.log("---------- sql execute --------\n proc: " + procedure); | ||
cmd = "declare " + (['@__return int'].concat((function() { | ||
var _ref2, _results; | ||
_ref2 = this.parameters; | ||
var _ref3, _results; | ||
_ref3 = this.parameters; | ||
_results = []; | ||
for (name in _ref2) { | ||
param = _ref2[name]; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
if (param.io === 2) { | ||
@@ -370,5 +473,5 @@ _results.push("@" + param.name + " " + (typeDeclaration(param.type))); | ||
spp = []; | ||
_ref2 = this.parameters; | ||
for (name in _ref2) { | ||
param = _ref2[name]; | ||
_ref3 = this.parameters; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
if (param.io === 2) { | ||
@@ -385,8 +488,7 @@ spp.push("@" + param.name + "=@" + param.name + " output"); | ||
cmd += "select " + (['@__return as \'__return\''].concat((function() { | ||
var _ref3, _results; | ||
_ref3 = this.parameters; | ||
var _ref4, _results; | ||
_ref4 = this.parameters; | ||
_results = []; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
for (name in _ref4) { | ||
param = _ref4[name]; | ||
if (param.io === 2) { | ||
@@ -403,4 +505,3 @@ _results.push("@" + param.name + " as '" + param.name + "'"); | ||
return this.query(cmd, function(err, recordsets) { | ||
var elapsed, last, returnValue, _ref3, _ref4; | ||
var elapsed, last, returnValue, _ref4, _ref5; | ||
_this.nested = false; | ||
@@ -416,8 +517,8 @@ if (err) { | ||
} else { | ||
last = (_ref3 = recordsets.pop()) != null ? _ref3[0] : void 0; | ||
last = (_ref4 = recordsets.pop()) != null ? _ref4[0] : void 0; | ||
if (last && (last.__return != null)) { | ||
returnValue = last.__return; | ||
_ref4 = _this.parameters; | ||
for (name in _ref4) { | ||
param = _ref4[name]; | ||
_ref5 = _this.parameters; | ||
for (name in _ref5) { | ||
param = _ref5[name]; | ||
if (!(param.io === 2)) { | ||
@@ -443,2 +544,10 @@ continue; | ||
MsnodesqlRequest.prototype.cancel = function() { | ||
/* | ||
Cancel currently executed request. | ||
*/ | ||
throw new Error("Request canceling is not implemented by msnodesql driver."); | ||
}; | ||
return MsnodesqlRequest; | ||
@@ -449,2 +558,3 @@ | ||
connection: MsnodesqlConnection, | ||
transaction: MsnodesqlTransaction, | ||
request: MsnodesqlRequest | ||
@@ -451,0 +561,0 @@ }; |
@@ -1,8 +0,8 @@ | ||
// Generated by CoffeeScript 1.6.2 | ||
// Generated by CoffeeScript 1.6.3 | ||
(function() { | ||
var ConnectionPool, TYPES, createColumns, getMssqlType, getTediousType, tds, util, | ||
var Pool, TYPES, createColumns, getMssqlType, getTediousType, tds, util, | ||
__hasProp = {}.hasOwnProperty, | ||
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; | ||
ConnectionPool = require('tedious-connection-pool'); | ||
Pool = require('generic-pool').Pool; | ||
@@ -15,2 +15,7 @@ tds = require('tedious'); | ||
/* | ||
@ignore | ||
*/ | ||
getTediousType = function(type) { | ||
@@ -65,2 +70,7 @@ switch (type) { | ||
/* | ||
@ignore | ||
*/ | ||
getMssqlType = function(type) { | ||
@@ -126,5 +136,9 @@ switch (type) { | ||
/* | ||
@ignore | ||
*/ | ||
createColumns = function(meta) { | ||
var key, out, value; | ||
out = {}; | ||
@@ -142,5 +156,9 @@ for (key in meta) { | ||
module.exports = function(Connection, Request) { | ||
var TediousConnection, TediousRequest, _ref, _ref1; | ||
/* | ||
@ignore | ||
*/ | ||
module.exports = function(Connection, Transaction, Request) { | ||
var TediousConnection, TediousRequest, TediousTransaction, _ref, _ref1, _ref2; | ||
TediousConnection = (function(_super) { | ||
@@ -157,5 +175,4 @@ __extends(TediousConnection, _super); | ||
TediousConnection.prototype.connect = function(config, callback) { | ||
var cfg, cfg_pool, _base, _base1, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, | ||
var cfg, cfg_pool, key, value, _base, _base1, _ref1, | ||
_this = this; | ||
cfg = { | ||
@@ -167,29 +184,43 @@ userName: config.user, | ||
}; | ||
if ((_ref1 = cfg.options) == null) { | ||
if (cfg.options == null) { | ||
cfg.options = {}; | ||
} | ||
if ((_ref2 = (_base = cfg.options).database) == null) { | ||
if ((_base = cfg.options).database == null) { | ||
_base.database = config.database; | ||
} | ||
if ((_ref3 = (_base1 = cfg.options).port) == null) { | ||
if ((_base1 = cfg.options).port == null) { | ||
_base1.port = config.port; | ||
} | ||
cfg_pool = (_ref4 = config.pool) != null ? _ref4 : {}; | ||
if ((_ref5 = cfg_pool.max) == null) { | ||
cfg_pool.max = 10; | ||
cfg_pool = { | ||
name: 'mssql', | ||
max: 10, | ||
min: 0, | ||
idleTimeoutMillis: 30000, | ||
create: function(callback) { | ||
var c; | ||
c = new tds.Connection(cfg); | ||
return c.once('connect', function(err) { | ||
if (err) { | ||
return callback(err, null); | ||
} | ||
return callback(null, c); | ||
}); | ||
}, | ||
destroy: function(c) { | ||
return c.close(); | ||
} | ||
}; | ||
if (config.pool) { | ||
_ref1 = config.pool; | ||
for (key in _ref1) { | ||
value = _ref1[key]; | ||
cfg_pool[key] = value; | ||
} | ||
} | ||
if ((_ref6 = cfg_pool.min) == null) { | ||
cfg_pool.min = 0; | ||
} | ||
if ((_ref7 = cfg_pool.idleTimeoutMillis) == null) { | ||
cfg_pool.idleTimeoutMillis = 30000; | ||
} | ||
this.pool = new ConnectionPool(cfg_pool, cfg); | ||
return this.pool.requestConnection(function(err, connection) { | ||
this.pool = Pool(cfg_pool, cfg); | ||
return this.pool.acquire(function(err, connection) { | ||
if (err && !(err instanceof Error)) { | ||
err = new Error(err); | ||
} | ||
if (connection != null) { | ||
connection.close(); | ||
} | ||
_this.pool.release(connection); | ||
return typeof callback === "function" ? callback(err) : void 0; | ||
@@ -200,8 +231,9 @@ }); | ||
TediousConnection.prototype.close = function(callback) { | ||
if (this.pool) { | ||
return this.pool.drain(function() { | ||
this.pool = null; | ||
return typeof callback === "function" ? callback(null) : void 0; | ||
}); | ||
} | ||
var _ref1, | ||
_this = this; | ||
return (_ref1 = this.pool) != null ? _ref1.drain(function() { | ||
_this.pool.destroyAllNow(); | ||
_this.pool = null; | ||
return typeof callback === "function" ? callback(null) : void 0; | ||
}) : void 0; | ||
}; | ||
@@ -212,2 +244,51 @@ | ||
})(Connection); | ||
TediousTransaction = (function(_super) { | ||
__extends(TediousTransaction, _super); | ||
function TediousTransaction() { | ||
_ref1 = TediousTransaction.__super__.constructor.apply(this, arguments); | ||
return _ref1; | ||
} | ||
TediousTransaction.prototype.begin = function(callback) { | ||
var _this = this; | ||
return this.connection.pool.acquire(function(err, connection) { | ||
if (err && !(err instanceof Error)) { | ||
err = new Error(err); | ||
} | ||
if (err) { | ||
return callback(err); | ||
} | ||
_this._pooledConnection = connection; | ||
return connection.beginTransaction(callback); | ||
}); | ||
}; | ||
TediousTransaction.prototype.commit = function(callback) { | ||
var _this = this; | ||
return this._pooledConnection.commitTransaction(function(err) { | ||
if (err && !(err instanceof Error)) { | ||
err = new Error(err); | ||
} | ||
_this.connection.pool.release(_this._pooledConnection); | ||
_this._pooledConnection = null; | ||
return callback(err); | ||
}); | ||
}; | ||
TediousTransaction.prototype.rollback = function(callback) { | ||
var _this = this; | ||
return this._pooledConnection.rollbackTransaction(function(err) { | ||
if (err && !(err instanceof Error)) { | ||
err = new Error(err); | ||
} | ||
_this.connection.pool.release(_this._pooledConnection); | ||
_this._pooledConnection = null; | ||
return callback(err); | ||
}); | ||
}; | ||
return TediousTransaction; | ||
})(Transaction); | ||
TediousRequest = (function(_super) { | ||
@@ -217,16 +298,30 @@ __extends(TediousRequest, _super); | ||
function TediousRequest() { | ||
_ref1 = TediousRequest.__super__.constructor.apply(this, arguments); | ||
return _ref1; | ||
_ref2 = TediousRequest.__super__.constructor.apply(this, arguments); | ||
return _ref2; | ||
} | ||
TediousRequest.prototype.connection = null; | ||
TediousRequest.prototype._acquire = function(callback) { | ||
if (this.transaction) { | ||
return this.transaction.queue(callback); | ||
} else { | ||
return this.connection.pool.acquire(callback); | ||
} | ||
}; | ||
TediousRequest.prototype._release = function(connection) { | ||
if (this.transaction) { | ||
return this.transaction.next(); | ||
} else { | ||
return this.connection.pool.release(connection); | ||
} | ||
}; | ||
/* | ||
Execute specified sql command. | ||
*/ | ||
TediousRequest.prototype.query = function(command, callback) { | ||
/* | ||
Execute specified sql command. | ||
*/ | ||
var columns, recordset, recordsets, started, | ||
_this = this; | ||
columns = {}; | ||
@@ -236,9 +331,4 @@ recordset = []; | ||
started = Date.now(); | ||
if (!this.connection.pool) { | ||
callback(new Error('MSSQL connection pool was not initialized!')); | ||
return; | ||
} | ||
return this.connection.pool.requestConnection(function(err, connection) { | ||
var name, param, req, _ref2, _ref3; | ||
return this._acquire(function(err, connection) { | ||
var name, param, req, _ref3, _ref4; | ||
if (!err) { | ||
@@ -250,3 +340,2 @@ if (_this.verbose) { | ||
var elapsed; | ||
if (err && !(err instanceof Error)) { | ||
@@ -269,3 +358,3 @@ err = new Error(err); | ||
} | ||
connection.close(); | ||
_this._release(connection); | ||
return typeof callback === "function" ? callback(err, _this.multiple ? recordsets : recordsets[0]) : void 0; | ||
@@ -275,3 +364,2 @@ }); | ||
var col, _i, _len, _results; | ||
_results = []; | ||
@@ -308,3 +396,2 @@ for (_i = 0, _len = metadata.length; _i < _len; _i++) { | ||
var col, exi, row, _i, _len; | ||
if (!recordset) { | ||
@@ -333,5 +420,5 @@ recordset = []; | ||
}); | ||
_ref2 = _this.parameters; | ||
for (name in _ref2) { | ||
param = _ref2[name]; | ||
_ref3 = _this.parameters; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
if (!(param.io === 1)) { | ||
@@ -349,5 +436,5 @@ continue; | ||
} | ||
_ref3 = _this.parameters; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
_ref4 = _this.parameters; | ||
for (name in _ref4) { | ||
param = _ref4[name]; | ||
if (param.io === 2) { | ||
@@ -363,3 +450,3 @@ req.addOutputParameter(param.name, getTediousType(param.type)); | ||
if (connection) { | ||
connection.close(); | ||
_this._release(connection); | ||
} | ||
@@ -371,10 +458,10 @@ return typeof callback === "function" ? callback(err) : void 0; | ||
/* | ||
Execute stored procedure with specified parameters. | ||
*/ | ||
TediousRequest.prototype.execute = function(procedure, callback) { | ||
/* | ||
Execute stored procedure with specified parameters. | ||
*/ | ||
var columns, recordset, recordsets, returnValue, started, | ||
_this = this; | ||
columns = {}; | ||
@@ -385,9 +472,4 @@ recordset = []; | ||
started = Date.now(); | ||
if (!this.connection.pool) { | ||
callback(new Error('MSSQL connection pool was not initialized!')); | ||
return; | ||
} | ||
return this.connection.pool.requestConnection(function(err, connection) { | ||
var name, param, req, _ref2, _ref3; | ||
return this._acquire(function(err, connection) { | ||
var name, param, req, _ref3, _ref4; | ||
if (!err) { | ||
@@ -399,3 +481,2 @@ if (_this.verbose) { | ||
var elapsed; | ||
if (err && !(err instanceof Error)) { | ||
@@ -413,3 +494,3 @@ err = new Error(err); | ||
} | ||
connection.close(); | ||
_this._release(connection); | ||
return typeof callback === "function" ? callback(err, recordsets, returnValue) : void 0; | ||
@@ -419,3 +500,2 @@ }); | ||
var col, _i, _len, _results; | ||
_results = []; | ||
@@ -430,3 +510,2 @@ for (_i = 0, _len = metadata.length; _i < _len; _i++) { | ||
var col, exi, row, _i, _len; | ||
if (!recordset) { | ||
@@ -477,5 +556,5 @@ recordset = []; | ||
}); | ||
_ref2 = _this.parameters; | ||
for (name in _ref2) { | ||
param = _ref2[name]; | ||
_ref3 = _this.parameters; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
if (!(param.io === 1)) { | ||
@@ -493,5 +572,5 @@ continue; | ||
} | ||
_ref3 = _this.parameters; | ||
for (name in _ref3) { | ||
param = _ref3[name]; | ||
_ref4 = _this.parameters; | ||
for (name in _ref4) { | ||
param = _ref4[name]; | ||
if (param.io === 2) { | ||
@@ -507,3 +586,3 @@ req.addOutputParameter(param.name, getTediousType(param.type)); | ||
if (connection) { | ||
connection.close(); | ||
_this._release(connection); | ||
} | ||
@@ -515,2 +594,11 @@ return typeof callback === "function" ? callback(err) : void 0; | ||
/* | ||
Cancel currently executed request. | ||
*/ | ||
TediousRequest.prototype.cancel = function() { | ||
throw new Error("Request canceling is not implemented by Tedious driver."); | ||
}; | ||
return TediousRequest; | ||
@@ -521,2 +609,3 @@ | ||
connection: TediousConnection, | ||
transaction: TediousTransaction, | ||
request: TediousRequest | ||
@@ -523,0 +612,0 @@ }; |
@@ -13,5 +13,9 @@ { | ||
"msnodesql", | ||
"sqlserver" | ||
"sqlserver", | ||
"tds", | ||
"node-tds", | ||
"tedious", | ||
"node-sqlserver" | ||
], | ||
"version": "0.3.4", | ||
"version": "0.4.0", | ||
"main": "index.js", | ||
@@ -30,3 +34,3 @@ "repository": { | ||
"tedious": ">=0.1.5", | ||
"tedious-connection-pool": ">=0.1.1" | ||
"generic-pool": ">=2.0.4" | ||
}, | ||
@@ -33,0 +37,0 @@ "devDependencies": { |
295
README.md
@@ -7,6 +7,20 @@ # node-mssql [![Dependency Status](https://david-dm.org/patriksimek/node-mssql.png)](https://david-dm.org/patriksimek/node-mssql) [![NPM version](https://badge.fury.io/js/mssql.png)](http://badge.fury.io/js/mssql) | ||
At the moment it support two TDS modules: | ||
**Extra features:** | ||
* Unified interface for multiple MSSQL modules | ||
* Connection pooling with Transactions support | ||
* Parametrized Stored Procedures in [node-tds](https://github.com/cretz/node-tds) and [Microsoft Driver for Node.js for SQL Server](https://github.com/WindowsAzure/node-sqlserver) | ||
At the moment it support three TDS modules: | ||
* [Tedious](https://github.com/pekim/tedious) by Mike D Pilsbury (pure javascript - windows/osx/linux) | ||
* [Microsoft Driver for Node.js for SQL Server](https://github.com/WindowsAzure/node-sqlserver) by Microsoft Corporation (native - windows only) | ||
* [node-tds](https://github.com/cretz/node-tds) by Chad Retz (pure javascript - windows/osx/linux) | ||
## What's new in 0.4 | ||
* Added support for transactions. | ||
* [node-tds](https://github.com/cretz/node-tds) is now available as an optional TDS driver. | ||
* Documentation updated to [CSDoc](https://github.com/patriksimek/csdoc) spec. | ||
* Tedious driver no longer use [tedious-connection-pool](https://github.com/pekim/tedious-connection-pool) for connection pooling | ||
* [Microsoft Driver for Node.js for SQL Server](https://github.com/WindowsAzure/node-sqlserver) is now pooled | ||
## Installation | ||
@@ -21,27 +35,32 @@ | ||
config = { | ||
user: '...', | ||
password: '...', | ||
server: 'localhost', | ||
database: '...' | ||
var config = { | ||
user: '...', | ||
password: '...', | ||
server: 'localhost', | ||
database: '...' | ||
} | ||
var connection = new sql.Connection(config, function(err) { | ||
// ... error checks | ||
// Query | ||
// Query | ||
var request = new sql.Request(connection1); // or: var request = connection.request(); | ||
request.query('select 1 as number', function(err, recordset) { | ||
// ... error checks | ||
console.dir(recordset); | ||
}); | ||
var request = new sql.Request(connection1); // or: var request = connection.request(); | ||
request.query('select 1 as number', function(err, recordset) { | ||
console.dir(recordset); | ||
}); | ||
// Stored Procedure | ||
// Stored Procedure | ||
var request = new sql.Request(connection1); | ||
request.input('input_parameter', sql.Int, value); | ||
request.output('output_parameter', sql.Int); | ||
request.execute('procedure_name', function(err, recordsets, returnValue) { | ||
// ... error checks | ||
console.dir(recordsets); | ||
}); | ||
var request = new sql.Request(connection1); | ||
request.input('input_parameter', sql.Int, value); | ||
request.output('output_parameter', sql.Int); | ||
request.execute('procedure_name', function(err, recordsets, returnValue) { | ||
console.dir(recordsets); | ||
}); | ||
}); | ||
@@ -55,26 +74,31 @@ ``` | ||
config = { | ||
user: '...', | ||
password: '...', | ||
server: 'localhost', | ||
database: '...' | ||
var config = { | ||
user: '...', | ||
password: '...', | ||
server: 'localhost', | ||
database: '...' | ||
} | ||
sql.connect(config, function(err) { | ||
// ... error checks | ||
// Query | ||
// Query | ||
var request = new sql.Request(); | ||
request.query('select 1 as number', function(err, recordset) { | ||
console.dir(recordset); | ||
}); | ||
var request = new sql.Request(); | ||
request.query('select 1 as number', function(err, recordset) { | ||
// ... error checks | ||
console.dir(recordset); | ||
}); | ||
// Stored Procedure | ||
// Stored Procedure | ||
var request = new sql.Request(); | ||
request.input('input_parameter', sql.Int, value); | ||
request.output('output_parameter', sql.Int); | ||
request.execute('procedure_name', function(err, recordsets, returnValue) { | ||
console.dir(recordsets); | ||
}); | ||
var request = new sql.Request(); | ||
request.input('input_parameter', sql.Int, value); | ||
request.output('output_parameter', sql.Int); | ||
request.execute('procedure_name', function(err, recordsets, returnValue) { | ||
// ... error checks | ||
console.dir(recordsets); | ||
}); | ||
@@ -91,2 +115,3 @@ }); | ||
* [Microsoft Driver for Node.js for SQL Server](#cfg-msnodesql) | ||
* [node-tds](#cfg-node-tds) | ||
@@ -105,2 +130,8 @@ ### Connection | ||
### Transaction | ||
* [begin](#begin) | ||
* [commit](#commit) | ||
* [rollback](#rollback) | ||
### Other | ||
@@ -111,2 +142,3 @@ | ||
* [Verbose Mode](#verbose) | ||
* [Known issues](#issues) | ||
@@ -116,3 +148,13 @@ ## Configuration | ||
```javascript | ||
config = { ... } | ||
var config = { | ||
user: '...', | ||
password: '...', | ||
server: 'localhost', | ||
database: '...', | ||
pool: { | ||
max: 10, | ||
min: 0, | ||
idleTimeoutMillis: 30000 | ||
} | ||
} | ||
``` | ||
@@ -129,7 +171,2 @@ | ||
* **database** - Database to connect to (default: dependent on server configuration). | ||
<a name="cfg-tedious" /> | ||
### Tedious | ||
* **options** - Tedious specific options. More information: http://pekim.github.io/tedious/api-connection.html | ||
* **pool.max** - The maximum number of connections there can be in the pool (default: `10`). | ||
@@ -139,17 +176,6 @@ * **pool.min** - The minimun of connections there can be in the pool (default: `0`). | ||
__Example__ | ||
<a name="cfg-tedious" /> | ||
### Tedious | ||
```javascript | ||
config = { | ||
options: { | ||
// tedious options | ||
}, | ||
pool: { | ||
max: 10, | ||
min: 0, | ||
idleTimeoutMillis: 30000 | ||
} | ||
} | ||
``` | ||
* **options** - Object of Tedious specific options. More information: http://pekim.github.io/tedious/api-connection.html | ||
@@ -159,6 +185,11 @@ <a name="cfg-msnodesql" /> | ||
This driver is not part of the default package and you must install it separately. | ||
This driver is not part of the default package and must be installed separately by 'npm install msnodesql'. If you are looking for compiled binaries, see [node-sqlserver-binary](https://github.com/jorgeazevedo/node-sqlserver-binary). | ||
* **connectionString** - Connection string (default: `Driver={SQL Server Native Client 11.0};Server=#{server},#{port};Database=#{database};Uid=#{user};Pwd=#{password};`). | ||
<a name="cfg-node-tds" /> | ||
### node-tds | ||
This driver is not part of the default package and must be installed separately by 'npm install tds'. | ||
## Connection | ||
@@ -183,10 +214,10 @@ | ||
var connection = new sql.Connection({ | ||
user: '...', | ||
password: '...', | ||
server: 'localhost', | ||
database: '...' | ||
user: '...', | ||
password: '...', | ||
server: 'localhost', | ||
database: '...' | ||
}); | ||
connection.connect(function(err) { | ||
// ... | ||
// ... | ||
}); | ||
@@ -233,9 +264,11 @@ ``` | ||
request.execute('procedure_name', function(err, recordsets, returnValue) { | ||
console.log(recordsets.length); // count of recordsets returned by procedure | ||
console.log(recordset[0].length); // count of rows contained in first recordset | ||
console.log(returnValue); // procedure return value | ||
// ... error checks | ||
console.log(recordsets.length); // count of recordsets returned by procedure | ||
console.log(recordset[0].length); // count of rows contained in first recordset | ||
console.log(returnValue); // procedure return value | ||
console.log(request.parameters.output_parameter.value); // output value | ||
console.log(request.parameters.output_parameter.value); // output value | ||
// ... | ||
// ... | ||
}); | ||
@@ -320,5 +353,7 @@ ``` | ||
request.query('select 1 as number', function(err, recordset) { | ||
console.log(recordset[0].number); // return 1 | ||
// ... error checks | ||
console.log(recordset[0].number); // return 1 | ||
// ... | ||
// ... | ||
}); | ||
@@ -334,9 +369,103 @@ ``` | ||
request.query('select 1 as number; select 2 as number', function(err, recordsets) { | ||
console.log(recordsets[0][0].number); // return 1 | ||
console.log(recordsets[1][0].number); // return 2 | ||
// ... | ||
// ... error checks | ||
console.log(recordsets[0][0].number); // return 1 | ||
console.log(recordsets[1][0].number); // return 2 | ||
}); | ||
``` | ||
## Transaction | ||
```javascript | ||
var transaction = new sql.Transaction(/* [connection] */); | ||
``` | ||
If you ommit connection argument, global connection is used instead. | ||
__Example__ | ||
```javascript | ||
var transaction = new sql.Transaction(/* [connection] */); | ||
transaction.begin(function(err) { | ||
// ... error checks | ||
var request = new sql.Request(transaction); | ||
request.query('insert into mytable (mycolumn) values (12345)', function(err, recordset) { | ||
// ... error checks | ||
transaction.commit(function(err, recordset) { | ||
// ... error checks | ||
console.log("Transaction commited."); | ||
}); | ||
}); | ||
}); | ||
``` | ||
<a name="begin" /> | ||
### begin(callback) | ||
Begin a transaction. | ||
__Arguments__ | ||
* **callback(err)** - A callback which is called after transaction has began, or an error has occurred. | ||
__Example__ | ||
```javascript | ||
var transaction = new sql.Transaction(); | ||
transaction.begin(function(err) { | ||
// ... | ||
}); | ||
``` | ||
--------------------------------------- | ||
<a name="commit" /> | ||
### commit(callback) | ||
Commit a transaction. | ||
__Arguments__ | ||
* **callback(err)** - A callback which is called after transaction has commited, or an error has occurred. | ||
__Example__ | ||
```javascript | ||
var transaction = new sql.Transaction(); | ||
transaction.begin(function(err) { | ||
// ... | ||
transaction.commit(function(err) { | ||
//... | ||
}) | ||
}); | ||
``` | ||
--------------------------------------- | ||
<a name="rollback" /> | ||
### rollback(callback) | ||
Rollback a transaction. | ||
__Arguments__ | ||
* **callback(err)** - A callback which is called after transaction has rolled back, or an error has occurred. | ||
__Example__ | ||
```javascript | ||
var transaction = new sql.Transaction(); | ||
transaction.begin(function(err) { | ||
// ... | ||
transaction.rollback(function(err) { | ||
//... | ||
}) | ||
}); | ||
``` | ||
<a name="data-types" /> | ||
@@ -350,6 +479,6 @@ ## Metadata | ||
request.query('select 1 as first, \'asdf\' as second', function(err, recordset) { | ||
console.dir(recordset.columns); | ||
console.dir(recordset.columns); | ||
console.log(recordset.columns.first.type === sql.Int); // true | ||
console.log(recordset.columns.second.type === sql.VarChar); // true | ||
console.log(recordset.columns.first.type === sql.Int); // true | ||
console.log(recordset.columns.second.type === sql.VarChar); // true | ||
}); | ||
@@ -440,2 +569,16 @@ ``` | ||
<a name="issues" /> | ||
## Known issues | ||
### Tedious | ||
* Tedious 1.5 contains bug where 0 is casted as null when using BigInt. [fix here](https://github.com/pekim/tedious/pull/113) | ||
* Tedious 1.5 doesn't support encoding of input parameters. [fix here](https://github.com/pekim/tedious/pull/113) | ||
### node-tds | ||
* node-tds 0.1.0 contains bug and return same value for columns with same name. | ||
* node-tds 0.1.0 doesn't support encoding of input parameters. | ||
* node-tds 0.1.0 contains bug in selects that doesn't return any values *(select @param = 'value')*. | ||
## TODO | ||
@@ -442,0 +585,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
133560
16
2145
585
+ Addedgeneric-pool@>=2.0.4
+ Addedgeneric-pool@3.9.0(transitive)
- Removedtedious-connection-pool@>=0.1.1
- Removedbabel-runtime@6.26.0(transitive)
- Removedbig-number@0.3.1(transitive)
- Removedbl@1.2.3(transitive)
- Removedcore-js@2.6.12(transitive)
- Removedcore-util-is@1.0.3(transitive)
- Removeddns-lookup-all@1.0.2(transitive)
- Removediconv-lite@0.4.24(transitive)
- Removedisarray@1.0.0(transitive)
- Removedprocess-nextick-args@2.0.1(transitive)
- Removedreadable-stream@2.3.8(transitive)
- Removedregenerator-runtime@0.11.1(transitive)
- Removedsemver@5.7.2(transitive)
- Removedsprintf@0.1.5(transitive)
- Removedstring_decoder@1.1.1(transitive)
- Removedtedious@1.15.0(transitive)
- Removedtedious-connection-pool@1.0.5(transitive)
- Removedutil-deprecate@1.0.2(transitive)