UNPKG

mssql2

Version:

Microsoft SQL Server client for Node.js (fork)

1,354 lines (1,291 loc) 49.3 kB
// Generated by CoffeeScript 1.10.0 (function() { var DECLARATIONS, JSON_COLUMN_ID, Pool, TYPES, Table, UDT, XML_COLUMN_ID, bindDomain, cast, createColumns, declare, getMssqlType, getTediousType, parameterCorrection, ref, tds, util, valueCorrection, extend = 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; }, hasProp = {}.hasOwnProperty; Pool = require('generic-pool').Pool; tds = require('tedious'); util = require('util'); ref = require('./datatypes'), TYPES = ref.TYPES, declare = ref.declare, cast = ref.cast; DECLARATIONS = require('./datatypes').DECLARATIONS; UDT = require('./udt').PARSERS; Table = require('./table'); JSON_COLUMN_ID = 'JSON_F52E2B61-18A1-11d1-B105-00805F49916B'; XML_COLUMN_ID = 'XML_F52E2B61-18A1-11d1-B105-00805F49916B'; /* @ignore */ bindDomain = function(cb) { var ref1; if (process.domain) { return (ref1 = process.domain) != null ? ref1.bind(cb) : void 0; } else { return cb; } }; /* @ignore */ getTediousType = function(type) { switch (type) { case TYPES.VarChar: return tds.TYPES.VarChar; case TYPES.NVarChar: return tds.TYPES.NVarChar; case TYPES.Text: return tds.TYPES.Text; case TYPES.Int: return tds.TYPES.Int; case TYPES.BigInt: return tds.TYPES.BigInt; case TYPES.TinyInt: return tds.TYPES.TinyInt; case TYPES.SmallInt: return tds.TYPES.SmallInt; case TYPES.Bit: return tds.TYPES.Bit; case TYPES.Float: return tds.TYPES.Float; case TYPES.Decimal: return tds.TYPES.Decimal; case TYPES.Numeric: return tds.TYPES.Numeric; case TYPES.Real: return tds.TYPES.Real; case TYPES.Money: return tds.TYPES.Money; case TYPES.SmallMoney: return tds.TYPES.SmallMoney; case TYPES.Time: return tds.TYPES.TimeN; case TYPES.Date: return tds.TYPES.DateN; case TYPES.DateTime: return tds.TYPES.DateTime; case TYPES.DateTime2: return tds.TYPES.DateTime2N; case TYPES.DateTimeOffset: return tds.TYPES.DateTimeOffsetN; case TYPES.SmallDateTime: return tds.TYPES.SmallDateTime; case TYPES.UniqueIdentifier: return tds.TYPES.UniqueIdentifierN; case TYPES.Xml: return tds.TYPES.VarChar; case TYPES.Char: return tds.TYPES.Char; case TYPES.NChar: return tds.TYPES.NChar; case TYPES.NText: return tds.TYPES.NVarChar; case TYPES.Image: return tds.TYPES.Image; case TYPES.Binary: return tds.TYPES.Binary; case TYPES.VarBinary: return tds.TYPES.VarBinary; case TYPES.UDT: case TYPES.Geography: case TYPES.Geometry: return tds.TYPES.UDT; case TYPES.TVP: return tds.TYPES.TVP; case TYPES.Variant: return tds.TYPES.Variant; default: return type; } }; /* @ignore */ getMssqlType = function(type, length) { switch (type) { case tds.TYPES.Char: return TYPES.Char; case tds.TYPES.NChar: return TYPES.NChar; case tds.TYPES.VarChar: return TYPES.VarChar; case tds.TYPES.NVarChar: return TYPES.NVarChar; case tds.TYPES.Text: return TYPES.Text; case tds.TYPES.NText: return TYPES.NText; case tds.TYPES.Int: return TYPES.Int; case tds.TYPES.IntN: if (length === 8) { return TYPES.BigInt; } if (length === 4) { return TYPES.Int; } if (length === 2) { return TYPES.SmallInt; } return TYPES.TinyInt; case tds.TYPES.BigInt: return TYPES.BigInt; case tds.TYPES.TinyInt: return TYPES.TinyInt; case tds.TYPES.SmallInt: return TYPES.SmallInt; case tds.TYPES.Bit: case tds.TYPES.BitN: return TYPES.Bit; case tds.TYPES.Float: return TYPES.Float; case tds.TYPES.FloatN: if (length === 8) { return TYPES.FloatN; } return TYPES.Real; case tds.TYPES.Real: return TYPES.Real; case tds.TYPES.Money: return TYPES.Money; case tds.TYPES.MoneyN: if (length === 8) { return TYPES.Money; } return TYPES.SmallMoney; case tds.TYPES.SmallMoney: return TYPES.SmallMoney; case tds.TYPES.Numeric: case tds.TYPES.NumericN: return TYPES.Numeric; case tds.TYPES.Decimal: case tds.TYPES.DecimalN: return TYPES.Decimal; case tds.TYPES.DateTime: return TYPES.DateTime; case tds.TYPES.DateTimeN: if (length === 8) { return TYPES.DateTime; } return TYPES.SmallDateTime; case tds.TYPES.TimeN: return TYPES.Time; case tds.TYPES.DateN: return TYPES.Date; case tds.TYPES.DateTime2N: return TYPES.DateTime2; case tds.TYPES.DateTimeOffsetN: return TYPES.DateTimeOffset; case tds.TYPES.SmallDateTime: return TYPES.SmallDateTime; case tds.TYPES.UniqueIdentifierN: return TYPES.UniqueIdentifier; case tds.TYPES.Image: return TYPES.Image; case tds.TYPES.Binary: return TYPES.Binary; case tds.TYPES.VarBinary: return TYPES.VarBinary; case tds.TYPES.Xml: return TYPES.Xml; case tds.TYPES.UDT: return TYPES.UDT; case tds.TYPES.TVP: return TYPES.TVP; case tds.TYPES.Variant: return TYPES.Variant; } }; /* @ignore */ createColumns = function(metadata) { var column, i, index, len, out; out = {}; for (index = i = 0, len = metadata.length; i < len; index = ++i) { column = metadata[index]; out[column.colName] = { index: index, name: column.colName, length: column.dataLength, type: getMssqlType(column.type, column.dataLength), scale: column.scale, precision: column.precision, nullable: !!(column.flags & 0x01), caseSensitive: !!(column.flags & 0x02), identity: !!(column.flags & 0x10), readOnly: !(column.flags & 0x0C) }; if (column.udtInfo != null) { out[column.colName].udt = { name: column.udtInfo.typeName, database: column.udtInfo.dbname, schema: column.udtInfo.owningSchema, assembly: column.udtInfo.assemblyName }; if (DECLARATIONS[column.udtInfo.typeName]) { out[column.colName].type = DECLARATIONS[column.udtInfo.typeName]; } } } return out; }; /* @ignore */ valueCorrection = function(value, metadata) { if (metadata.type === tds.TYPES.UDT && (value != null)) { if (UDT[metadata.udtInfo.typeName]) { return UDT[metadata.udtInfo.typeName](value); } else { return value; } } else { return value; } }; /* @ignore */ parameterCorrection = function(value) { var col, i, len, ref1, tvp; if (value instanceof Table) { tvp = { name: value.name, schema: value.schema, columns: [], rows: value.rows }; ref1 = value.columns; for (i = 0, len = ref1.length; i < len; i++) { col = ref1[i]; tvp.columns.push({ name: col.name, type: getTediousType(col.type), length: col.length, scale: col.scale, precision: col.precision }); } return tvp; } else { return value; } }; /* @ignore */ module.exports = function(Connection, Transaction, Request, ConnectionError, TransactionError, RequestError) { var TediousConnection, TediousRequest, TediousTransaction; TediousConnection = (function(superClass) { extend(TediousConnection, superClass); function TediousConnection() { return TediousConnection.__super__.constructor.apply(this, arguments); } TediousConnection.prototype.pool = null; TediousConnection.prototype.connect = function(config, callback) { var base, base1, base2, base3, base4, base5, cfg, cfg_pool, key, ref1, ref2, ref3, ref4, value; cfg = { userName: config.user, password: config.password, server: config.server, options: config.options, domain: config.domain }; if ((base = cfg.options).database == null) { base.database = config.database; } if ((base1 = cfg.options).port == null) { base1.port = config.port; } if ((base2 = cfg.options).connectTimeout == null) { base2.connectTimeout = (ref1 = (ref2 = config.connectionTimeout) != null ? ref2 : config.timeout) != null ? ref1 : 15000; } if ((base3 = cfg.options).requestTimeout == null) { base3.requestTimeout = (ref3 = config.requestTimeout) != null ? ref3 : 15000; } if ((base4 = cfg.options).tdsVersion == null) { base4.tdsVersion = '7_4'; } cfg.options.rowCollectionOnDone = false; cfg.options.rowCollectionOnRequestCompletion = false; cfg.options.useColumnNames = false; if ((base5 = cfg.options).appName == null) { base5.appName = 'node-mssql'; } if (cfg.options.instanceName) { delete cfg.options.port; } if (isNaN(cfg.options.requestTimeout)) { cfg.options.requestTimeout = 15000; } if (cfg.options.requestTimeout === Infinity) { cfg.options.requestTimeout = 0; } if (cfg.options.requestTimeout < 0) { cfg.options.requestTimeout = 0; } if (config.debug) { cfg.options.debug = { packet: true, token: true, data: true, payload: true }; } cfg_pool = { name: 'mssql', max: 10, min: 0, idleTimeoutMillis: 30000, create: (function(_this) { return function(callback) { var c; c = new tds.Connection(cfg); c.once('connect', function(err) { if (err) { err = ConnectionError(err); } if (err) { return callback(err, null); } return callback(null, c); }); c.on('error', function(err) { if (err.code === 'ESOCKET') { c.hasError = true; return; } return _this.emit('error', err); }); if (config.debug) { return c.on('debug', function(msg) { return _this._debug(msg); }); } }; })(this), validate: function(c) { return (c != null) && !c.closed && !c.hasError; }, destroy: function(c) { if (c != null) { c.close(); } return setTimeout(function() { return c != null ? c.removeAllListeners() : void 0; }, 500); } }; if (config.pool) { ref4 = config.pool; for (key in ref4) { value = ref4[key]; cfg_pool[key] = value; } } this.pool = Pool(cfg_pool, cfg); return this.pool.acquire((function(_this) { return function(err, connection) { if (err) { _this.pool.drain(function() { var ref5; if ((ref5 = _this.pool) != null) { ref5.destroyAllNow(); } return _this.pool = null; }); } else { _this.pool.release(connection); } return callback(err); }; })(this)); }; TediousConnection.prototype.close = function(callback) { if (!this.pool) { return callback(null); } return this.pool.drain((function(_this) { return function() { var ref1; if ((ref1 = _this.pool) != null) { ref1.destroyAllNow(); } _this.pool = null; return callback(null); }; })(this)); }; return TediousConnection; })(Connection); TediousTransaction = (function(superClass) { extend(TediousTransaction, superClass); function TediousTransaction() { return TediousTransaction.__super__.constructor.apply(this, arguments); } TediousTransaction.prototype._abort = function() { var pc; if (!this._rollbackRequested) { pc = this._pooledConnection; setImmediate((function(_this) { return function() { return _this.connection.pool.release(pc); }; })(this)); this._pooledConnection.removeListener('rollbackTransaction', this._abort); this._pooledConnection = null; this._aborted = true; return this.emit('rollback', true); } }; TediousTransaction.prototype.begin = function(callback) { this._aborted = false; this._rollbackRequested = false; return this.connection.pool.acquire((function(_this) { return function(err, connection) { if (err) { return callback(err); } _this._pooledConnection = connection; _this._pooledConnection.on('rollbackTransaction', _this._abort); return connection.beginTransaction(bindDomain(function(err) { if (err) { err = TransactionError(err); } return callback(err); }, _this.name, _this.isolationLevel)); }; })(this)); }; TediousTransaction.prototype.commit = function(callback) { return this._pooledConnection.commitTransaction(bindDomain((function(_this) { return function(err) { if (err) { err = TransactionError(err); } _this._pooledConnection.removeListener('rollbackTransaction', _this._abort); _this.connection.pool.release(_this._pooledConnection); _this._pooledConnection = null; return callback(err); }; })(this))); }; TediousTransaction.prototype.rollback = function(callback) { this._rollbackRequested = true; return this._pooledConnection.rollbackTransaction(bindDomain((function(_this) { return function(err) { if (err) { err = TransactionError(err); } _this._pooledConnection.removeListener('rollbackTransaction', _this._abort); _this.connection.pool.release(_this._pooledConnection); _this._pooledConnection = null; return callback(err); }; })(this))); }; return TediousTransaction; })(Transaction); TediousRequest = (function(superClass) { extend(TediousRequest, superClass); function TediousRequest() { return TediousRequest.__super__.constructor.apply(this, arguments); } /* Execute specified sql batch. */ TediousRequest.prototype.batch = function(batch, callback) { this._isBatch = true; return TediousRequest.prototype.query.call(this, batch, callback); }; /* Bulk load. */ TediousRequest.prototype.bulk = function(table, callback) { var errorHandlers, errors, handleError, handleInfo, hasReturned, started; table._makeBulk(); if (!table.name) { process.nextTick(function() { return callback(RequestError("Table name must be specified for bulk insert.", "ENAME")); }); } if (table.name.charAt(0) === '@') { process.nextTick(function() { return callback(RequestError("You can't use table variables for bulk insert.", "ENAME")); }); } started = Date.now(); errors = []; errorHandlers = {}; hasReturned = false; handleError = (function(_this) { return function(doReturn, connection, info) { var e, err, event, handler; err = new Error(info.message); err.info = info; e = RequestError(err, 'EREQUEST'); if (_this.stream) { _this.emit('error', e); } else { if (doReturn && !hasReturned) { if (connection != null) { for (event in errorHandlers) { handler = errorHandlers[event]; connection.removeListener(event, handler); } _this._release(connection); } hasReturned = true; if (typeof callback === "function") { callback(e); } } } return errors.push(e); }; })(this); handleInfo = (function(_this) { return function(msg) { return _this.emit('info', { message: msg.message, number: msg.number, state: msg.state, "class": msg["class"], lineNumber: msg.lineNumber, serverName: msg.serverName, procName: msg.procName }); }; })(this); return this._acquire((function(_this) { return function(err, connection) { var bulk, col, done, i, j, len, len1, objectid, ref1, ref2, req, row; if (!err) { if (_this.verbose) { _this._log("-------- sql bulk load --------\n table: " + table.name); } if (_this.canceled) { if (_this.verbose) { _this._log("---------- canceling ----------"); } _this._release(connection); return typeof callback === "function" ? callback(new RequestError("Canceled.", 'ECANCEL')) : void 0; } _this._cancel = function() { if (_this.verbose) { _this._log("---------- canceling ----------"); } return connection.cancel(); }; errorHandlers['infoMessage'] = handleInfo; errorHandlers['errorMessage'] = handleError.bind(void 0, false, connection); errorHandlers['error'] = handleError.bind(void 0, true, connection); connection.on('infoMessage', errorHandlers['infoMessage']); connection.on('errorMessage', errorHandlers['errorMessage']); connection.on('error', errorHandlers['error']); done = bindDomain(function(err, rowCount) { var elapsed, error, event, handler, i, len, ref1; if (err && err.message !== ((ref1 = errors[errors.length - 1]) != null ? ref1.message : void 0)) { err = RequestError(err, 'EREQUEST'); if (_this.stream) { _this.emit('error', err); } errors.push(err); } if (_this.verbose) { if (errors.length) { for (i = 0, len = errors.length; i < len; i++) { error = errors[i]; _this._log(" error: " + error); } } elapsed = Date.now() - started; _this._log(" duration: " + elapsed + "ms"); _this._log("---------- completed ----------"); } _this._cancel = null; if (errors.length && !_this.stream) { error = errors.pop(); error.precedingErrors = errors; } if (!hasReturned) { for (event in errorHandlers) { handler = errorHandlers[event]; connection.removeListener(event, handler); } _this._release(connection); hasReturned = true; if (_this.stream) { return callback(null, null); } else { return typeof callback === "function" ? callback(error, rowCount) : void 0; } } }); bulk = connection.newBulkLoad(table.path, done); ref1 = table.columns; for (i = 0, len = ref1.length; i < len; i++) { col = ref1[i]; bulk.addColumn(col.name, getTediousType(col.type), { nullable: col.nullable, length: col.length, scale: col.scale, precision: col.precision }); } ref2 = table.rows; for (j = 0, len1 = ref2.length; j < len1; j++) { row = ref2[j]; bulk.addRow(row); } if (_this.verbose) { _this._log("---------- response -----------"); } if (table.create) { if (table.temporary) { objectid = "tempdb..[" + table.name + "]"; } else { objectid = table.path; } req = new tds.Request("if object_id('" + (objectid.replace(/'/g, '\'\'')) + "') is null " + (table.declare()), function(err) { if (err) { return done(err); } return connection.execBulkLoad(bulk); }); return connection.execSqlBatch(req); } else { return connection.execBulkLoad(bulk); } } }; })(this)); }; /* Execute specified sql command. */ TediousRequest.prototype.query = function(command, callback) { var batchHasOutput, batchLastRow, chunksBuffer, columns, errorHandlers, errors, handleError, handleInfo, hasReturned, isChunkedRecordset, isJSONRecordset, recordset, recordsets, started, xmlBuffer; columns = {}; recordset = []; recordsets = []; started = Date.now(); errors = []; batchLastRow = null; batchHasOutput = false; isJSONRecordset = false; isChunkedRecordset = false; chunksBuffer = null; xmlBuffer = null; hasReturned = false; errorHandlers = {}; handleError = (function(_this) { return function(doReturn, connection, info) { var e, err, event, handler; err = new Error(info.message); err.info = info; e = RequestError(err, 'EREQUEST'); if (_this.stream) { _this.emit('error', e); } else { if (doReturn && !hasReturned) { if (connection != null) { for (event in errorHandlers) { handler = errorHandlers[event]; connection.removeListener(event, handler); } _this._release(connection); } hasReturned = true; if (typeof callback === "function") { callback(e); } } } return errors.push(e); }; })(this); handleInfo = (function(_this) { return function(msg) { return _this.emit('info', { message: msg.message, number: msg.number, state: msg.state, "class": msg["class"], lineNumber: msg.lineNumber, serverName: msg.serverName, procName: msg.procName }); }; })(this); return this._acquire((function(_this) { return function(err, connection) { var assigns, declarations, doneHandler, name, param, ref1, ref2, req, selects, value; if (!err) { if (_this.verbose) { _this._log("---------- sql " + (_this._isBatch ? 'batch' : 'query') + " ----------\n " + (_this._isBatch ? 'batch' : 'query') + ": " + command); } if (_this.canceled) { if (_this.verbose) { _this._log("---------- canceling ----------"); } _this._release(connection); return typeof callback === "function" ? callback(new RequestError("Canceled.", 'ECANCEL')) : void 0; } _this._cancel = function() { if (_this.verbose) { _this._log("---------- canceling ----------"); } return connection.cancel(); }; errorHandlers['infoMessage'] = handleInfo; errorHandlers['errorMessage'] = handleError.bind(void 0, false, connection); errorHandlers['error'] = handleError.bind(void 0, true, connection); connection.on('infoMessage', errorHandlers['infoMessage']); connection.on('errorMessage', errorHandlers['errorMessage']); connection.on('error', errorHandlers['error']); req = new tds.Request(command, bindDomain(function(err) { var elapsed, error, event, handler, i, len, name, ref1, value; if (err && err.message !== ((ref1 = errors[errors.length - 1]) != null ? ref1.message : void 0)) { err = RequestError(err, 'EREQUEST'); if (_this.stream) { _this.emit('error', err); } errors.push(err); } if (batchHasOutput) { if (!_this.stream) { batchLastRow = recordsets.pop()[0]; } for (name in batchLastRow) { value = batchLastRow[name]; if (!(name !== '___return___')) { continue; } if (_this.verbose) { if (value === tds.TYPES.Null) { _this._log(" output: @" + name + ", null"); } else { _this._log(" output: @" + name + ", " + (_this.parameters[name].type.declaration.toLowerCase()) + ", " + value); } } _this.parameters[name].value = value === tds.TYPES.Null ? null : value; } } if (_this.verbose) { if (errors.length) { for (i = 0, len = errors.length; i < len; i++) { error = errors[i]; _this._log(" error: " + error); } } elapsed = Date.now() - started; _this._log(" duration: " + elapsed + "ms"); _this._log("---------- completed ----------"); } _this._cancel = null; if (errors.length && !_this.stream) { error = errors.pop(); error.precedingErrors = errors; } if (!hasReturned) { for (event in errorHandlers) { handler = errorHandlers[event]; connection.removeListener(event, handler); } _this._release(connection); hasReturned = true; if (_this.stream) { return callback(null, null); } else { return typeof callback === "function" ? callback(error, _this.multiple ? recordsets : recordsets[0]) : void 0; } } })); req.on('columnMetadata', function(metadata) { var ref1; columns = createColumns(metadata); isChunkedRecordset = false; if (metadata.length === 1 && ((ref1 = metadata[0].colName) === JSON_COLUMN_ID || ref1 === XML_COLUMN_ID)) { isChunkedRecordset = true; chunksBuffer = []; } if (_this.stream) { if (_this._isBatch) { if (columns["___return___"] == null) { return _this.emit('recordset', columns); } } else { return _this.emit('recordset', columns); } } }); doneHandler = function(rowCount, more) { var error1, ex, row; if (Object.keys(columns).length === 0) { if (rowCount > 0) { _this.rowsAffected += rowCount; } return; } if (isChunkedRecordset) { if (columns[JSON_COLUMN_ID] && _this.connection.config.parseJSON === true) { try { row = JSON.parse(chunksBuffer.join('')); } catch (error1) { ex = error1; row = null; ex = RequestError(new Error("Failed to parse incoming JSON. " + ex.message), 'EJSON'); if (_this.stream) { _this.emit('error', ex); } errors.push(ex); } } else { row = {}; row[Object.keys(columns)[0]] = chunksBuffer.join(''); } chunksBuffer = null; if (_this.verbose) { _this._log(util.inspect(row)); _this._log("---------- --------------------"); } if (_this.stream) { _this.emit('row', row); } else { recordset.push(row); } } if (!_this.stream) { Object.defineProperty(recordset, 'columns', { enumerable: false, value: columns }); Object.defineProperty(recordset, 'toTable', { enumerable: false, value: function() { return Table.fromRecordset(this); } }); recordsets.push(recordset); } recordset = []; return columns = {}; }; req.on('doneInProc', doneHandler); req.on('done', doneHandler); req.on('returnValue', function(parameterName, value, metadata) { if (_this.verbose) { if (value === tds.TYPES.Null) { _this._log(" output: @" + parameterName + ", null"); } else { _this._log(" output: @" + parameterName + ", " + (_this.parameters[parameterName].type.declaration.toLowerCase()) + ", " + value); } } return _this.parameters[parameterName].value = value === tds.TYPES.Null ? null : value; }); req.on('row', function(columns) { var col, exi, i, len, row; if (!recordset) { recordset = []; } if (isChunkedRecordset) { return chunksBuffer.push(columns[0].value); } else { row = {}; for (i = 0, len = columns.length; i < len; i++) { col = columns[i]; col.value = valueCorrection(col.value, col.metadata); exi = row[col.metadata.colName]; if (exi != null) { if (exi instanceof Array) { exi.push(col.value); } else { row[col.metadata.colName] = [exi, col.value]; } } else { row[col.metadata.colName] = col.value; } } if (_this.verbose) { _this._log(util.inspect(row)); _this._log("---------- --------------------"); } if (_this.stream) { if (_this._isBatch) { if (row["___return___"] != null) { return batchLastRow = row; } else { return _this.emit('row', row); } } else { return _this.emit('row', row); } } else { return recordset.push(row); } } }); if (_this._isBatch) { if (Object.keys(_this.parameters).length) { ref1 = _this.parameters; for (name in ref1) { param = ref1[name]; value = getTediousType(param.type).validate(param.value); if (value instanceof TypeError) { value = new RequestError("Validation failed for parameter \'" + name + "\'. " + value.message, 'EPARAM'); if (_this.verbose) { _this._log(" error: " + value); _this._log("---------- completed ----------"); } _this._release(connection); return typeof callback === "function" ? callback(value) : void 0; } param.value = value; } declarations = (function() { var ref2, results; ref2 = this.parameters; results = []; for (name in ref2) { param = ref2[name]; results.push("@" + name + " " + (declare(param.type, param))); } return results; }).call(_this); assigns = (function() { var ref2, results; ref2 = this.parameters; results = []; for (name in ref2) { param = ref2[name]; results.push("@" + name + " = " + (cast(param.value, param.type, param))); } return results; }).call(_this); selects = (function() { var ref2, results; ref2 = this.parameters; results = []; for (name in ref2) { param = ref2[name]; if (param.io === 2) { results.push("@" + name + " as [" + name + "]"); } } return results; }).call(_this); batchHasOutput = selects.length > 0; req.sqlTextOrProcedure = "declare " + (declarations.join(', ')) + ";select " + (assigns.join(', ')) + ";" + req.sqlTextOrProcedure + ";" + (batchHasOutput ? 'select 1 as [___return___], ' + selects.join(', ') : ''); } } else { ref2 = _this.parameters; for (name in ref2) { param = ref2[name]; if (_this.verbose) { if (param.value === tds.TYPES.Null) { _this._log(" " + (param.io === 1 ? " input" : "output") + ": @" + param.name + ", null"); } else { _this._log(" " + (param.io === 1 ? " input" : "output") + ": @" + param.name + ", " + (param.type.declaration.toLowerCase()) + ", " + param.value); } } if (param.io === 1) { req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision }); } else { req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision }); } } } if (_this.verbose) { _this._log("---------- response -----------"); } return connection[_this._isBatch ? 'execSqlBatch' : 'execSql'](req); } else { if (connection) { _this._release(connection); } return typeof callback === "function" ? callback(err) : void 0; } }; })(this)); }; /* Execute stored procedure with specified parameters. */ TediousRequest.prototype.execute = function(procedure, callback) { var chunksBuffer, columns, errorHandlers, errors, handleError, hasReturned, isChunkedRecordset, recordset, recordsets, returnValue, started; columns = {}; recordset = []; recordsets = []; returnValue = 0; started = Date.now(); errors = []; isChunkedRecordset = false; chunksBuffer = null; hasReturned = false; errorHandlers = {}; handleError = (function(_this) { return function(doReturn, connection, info) { var e, err, event, handler; err = new Error(info.message); err.info = info; e = RequestError(err, 'EREQUEST'); if (_this.stream) { _this.emit('error', e); } else { if (doReturn && !hasReturned) { if (connection != null) { for (event in errorHandlers) { handler = errorHandlers[event]; connection.removeListener(event, handler); } _this._release(connection); } hasReturned = true; if (typeof callback === "function") { callback(e); } } } return errors.push(e); }; })(this); return this._acquire((function(_this) { return function(err, connection) { var name, param, ref1, req; if (!err) { if (_this.verbose) { _this._log("---------- sql execute --------\n proc: " + procedure); } if (_this.canceled) { if (_this.verbose) { _this._log("---------- canceling ----------"); } _this._release(connection); return typeof callback === "function" ? callback(new RequestError("Canceled.", 'ECANCEL')) : void 0; } _this._cancel = function() { if (_this.verbose) { _this._log("---------- canceling ----------"); } return connection.cancel(); }; errorHandlers['errorMessage'] = handleError.bind(void 0, false, connection); errorHandlers['error'] = handleError.bind(void 0, true, connection); connection.on('errorMessage', errorHandlers['errorMessage']); connection.on('error', errorHandlers['error']); req = new tds.Request(procedure, bindDomain(function(err) { var elapsed, error, event, handler, i, len, ref1; if (err && err.message !== ((ref1 = errors[errors.length - 1]) != null ? ref1.message : void 0)) { err = RequestError(err, 'EREQUEST'); if (_this.stream) { _this.emit('error', err); } errors.push(err); } if (_this.verbose) { if (errors.length) { for (i = 0, len = errors.length; i < len; i++) { error = errors[i]; _this._log(" error: " + error); } } elapsed = Date.now() - started; _this._log(" return: " + returnValue); _this._log(" duration: " + elapsed + "ms"); _this._log("---------- completed ----------"); } _this._cancel = null; if (errors.length && !_this.stream) { error = errors.pop(); error.precedingErrors = errors; } if (!hasReturned) { for (event in errorHandlers) { handler = errorHandlers[event]; connection.removeListener(event, handler); } _this._release(connection); hasReturned = true; if (_this.stream) { return callback(null, null, returnValue); } else { recordsets.returnValue = returnValue; return typeof callback === "function" ? callback(error, recordsets, returnValue) : void 0; } } })); req.on('columnMetadata', function(metadata) { var ref1; columns = createColumns(metadata); isChunkedRecordset = false; if (metadata.length === 1 && ((ref1 = metadata[0].colName) === JSON_COLUMN_ID || ref1 === XML_COLUMN_ID)) { isChunkedRecordset = true; chunksBuffer = []; } if (_this.stream) { return _this.emit('recordset', columns); } }); req.on('row', function(columns) { var col, exi, i, len, row; if (!recordset) { recordset = []; } if (isChunkedRecordset) { return chunksBuffer.push(columns[0].value); } else { row = {}; for (i = 0, len = columns.length; i < len; i++) { col = columns[i]; col.value = valueCorrection(col.value, col.metadata); exi = row[col.metadata.colName]; if (exi != null) { if (exi instanceof Array) { exi.push(col.value); } else { row[col.metadata.colName] = [exi, col.value]; } } else { row[col.metadata.colName] = col.value; } } if (_this.verbose) { _this._log(util.inspect(row)); _this._log("---------- --------------------"); } if (_this.stream) { return _this.emit('row', row); } else { return recordset.push(row); } } }); req.on('doneInProc', function(rowCount, more) { var error1, ex, row; if (Object.keys(columns).length === 0) { if (rowCount > 0) { _this.rowsAffected += rowCount; } return; } if (isChunkedRecordset) { if (columns[JSON_COLUMN_ID] && _this.connection.config.parseJSON === true) { try { row = JSON.parse(chunksBuffer.join('')); } catch (error1) { ex = error1; row = null; ex = RequestError(new Error("Failed to parse incoming JSON. " + ex.message), 'EJSON'); if (_this.stream) { _this.emit('error', ex); } errors.push(ex); } } else { row = {}; row[Object.keys(columns)[0]] = chunksBuffer.join(''); } chunksBuffer = null; if (_this.verbose) { _this._log(util.inspect(row)); _this._log("---------- --------------------"); } if (_this.stream) { _this.emit('row', row); } else { recordset.push(row); } } if (!_this.stream) { Object.defineProperty(recordset, 'columns', { enumerable: false, value: columns }); Object.defineProperty(recordset, 'toTable', { enumerable: false, value: function() { return Table.fromRecordset(this); } }); recordsets.push(recordset); } recordset = []; return columns = {}; }); req.on('doneProc', function(rowCount, more, returnStatus) { return returnValue = returnStatus; }); req.on('returnValue', function(parameterName, value, metadata) { if (_this.verbose) { if (value === tds.TYPES.Null) { _this._log(" output: @" + parameterName + ", null"); } else { _this._log(" output: @" + parameterName + ", " + (_this.parameters[parameterName].type.declaration.toLowerCase()) + ", " + value); } } return _this.parameters[parameterName].value = value === tds.TYPES.Null ? null : value; }); ref1 = _this.parameters; for (name in ref1) { param = ref1[name]; if (_this.verbose) { if (param.value === tds.TYPES.Null) { _this._log(" " + (param.io === 1 ? " input" : "output") + ": @" + param.name + ", null"); } else { _this._log(" " + (param.io === 1 ? " input" : "output") + ": @" + param.name + ", " + (param.type.declaration.toLowerCase()) + ", " + param.value); } } if (param.io === 1) { req.addParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision }); } else { req.addOutputParameter(param.name, getTediousType(param.type), parameterCorrection(param.value), { length: param.length, scale: param.scale, precision: param.precision }); } } if (_this.verbose) { _this._log("---------- response -----------"); } return connection.callProcedure(req); } else { if (connection) { _this._release(connection); } return typeof callback === "function" ? callback(err) : void 0; } }; })(this)); }; /* Cancel currently executed request. */ TediousRequest.prototype.cancel = function() { if (this._cancel) { return this._cancel(); } return true; }; return TediousRequest; })(Request); return { Connection: TediousConnection, Transaction: TediousTransaction, Request: TediousRequest, fix: function() {} }; }; }).call(this);