UNPKG

tds

Version:

TDS client for connecting to Microsoft SQL Server

370 lines (331 loc) 13.2 kB
var EventEmitter, Statement, TdsClient, TdsError, TdsUtils, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.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; }; EventEmitter = require('events').EventEmitter; TdsClient = require('./tds-client').TdsClient; TdsUtils = require('./tds-utils').TdsUtils; /** Connection class for connecting to SQL Server */ exports.Connection = (function(_super) { __extends(Connection, _super); function Connection(_options) { var _ref, _ref2, _this = this; this._options = _options; this.end = __bind(this.end, this); this.rollback = __bind(this.rollback, this); this.commit = __bind(this.commit, this); this.setAutoCommit = __bind(this.setAutoCommit, this); this.prepareBulkLoad = __bind(this.prepareBulkLoad, this); this.createCall = __bind(this.createCall, this); this.createStatement = __bind(this.createStatement, this); this.connect = __bind(this.connect, this); this._autoCommit = true; this._client = new TdsClient({ error: function(err) { var cb, _base; if (_this._pendingCallback != null) { _this._currentStatement = null; cb = _this._pendingCallback; _this._pendingCallback = null; return cb(err); } else if (_this._pendingLoginCallback != null) { cb = _this._pendingLoginCallback; _this._pendingLoginCallback = null; return cb(err); } else if (_this._currentStatement != null) { return _this._currentStatement._error(err); } else if (_this.handler != null) { return typeof (_base = _this.handler).error === "function" ? _base.error(err) : void 0; } else { return _this.emit('error', err); } }, message: function(message) { var cb, err, _base, _base2; if (message.error) { err = new TdsError(message.text, message); if (_this._pendingCallback != null) { _this._currentStatement = null; cb = _this._pendingCallback; _this._pendingCallback = null; return cb(err); } else if (_this._pendingLoginCallback != null) { cb = _this._pendingLoginCallback; _this._pendingLoginCallback = null; return cb(err); } else if (_this._currentStatement != null) { return _this._currentStatement._error(err); } else if (_this.handler != null) { return typeof (_base = _this.handler).error === "function" ? _base.error(err) : void 0; } else { return _this.emit('error', err); } } else if (_this._currentStatement != null) { return _this._currentStatement._message(message); } else if (_this.handler != null) { return typeof (_base2 = _this.handler).message === "function" ? _base2.message(message) : void 0; } else { return _this.emit('message', message); } }, connect: function(connect) { return _this._client.login(_this._options); }, login: function(login) { var cb; cb = _this._pendingLoginCallback; _this._pendingLoginCallback = null; return typeof cb === "function" ? cb() : void 0; }, row: function(row) { var _ref; return (_ref = _this._currentStatement) != null ? _ref._row(row) : void 0; }, colmetadata: function(colmetadata) { var _ref; return (_ref = _this._currentStatement) != null ? _ref._colmetadata(colmetadata) : void 0; }, done: function(done) { var cb; if (done.hasMore) return; if (_this._pendingCallback != null) { if (_this._currentStatement === '#setAutoCommit') { _this._autoCommit = !_this._autoCommit; } _this._currentStatement = null; cb = _this._pendingCallback; _this._pendingCallback = null; return cb(); } else if (_this._currentStatement != null) { return _this._currentStatement._done(done); } } }); this._client.logError = (_ref = this._options) != null ? _ref.logError : void 0; this._client.logDebug = (_ref2 = this._options) != null ? _ref2.logDebug : void 0; } Connection.prototype.connect = function(_pendingLoginCallback) { this._pendingLoginCallback = _pendingLoginCallback; return this._client.connect(this._options); }; Connection.prototype.createStatement = function(sql, params, handler) { if (this._currentStatement) throw new Error('Statement currently running'); if (this._options.logDebug) { console.log('Creating statement: %s with params: ', sql, params); } return new Statement(this, sql, params, handler); }; Connection.prototype.createCall = function(procName, params, handler) { throw new Error('Not yet implemented'); }; Connection.prototype.prepareBulkLoad = function(tableName, batchSize, columns, cb) { throw new Error('Not yet implemented'); }; Connection.prototype.setAutoCommit = function(autoCommit, autoCommitCallback) { if (this._autoCommit === autoCommit) { return cb(); } else { if (this._currentStatement != null) { throw new Error('Cannot change auto commit while statement is executing'); } this._pendingCallback = autoCommitCallback; this._currentStatement = '#setAutoCommit'; if (autoCommit) { return this._client.sqlBatch('SET IMPLICIT_TRANSACTIONS OFF'); } else { return this._client.sqlBatch('SET IMPLICIT_TRANSACTIONS ON'); } } }; Connection.prototype.commit = function(commitCallback) { if (this._autoCommit) throw new Error('Auto commit is on'); if (this._currentStatement != null) { throw new Error('Cannot commit while statement is executing'); } this._pendingCallback = commitCallback; this._currentStatement = '#commit'; return this._client.sqlBatch('IF @@TRANCOUNT > 0 COMMIT TRANSACTION'); }; Connection.prototype.rollback = function(rollbackCallback) { if (this._autoCommit) throw new Error('Auto commit is on'); if (this._currentStatement != null) { throw new Error('Cannot rollback while statement is executing'); } this._pendingCallback = rollbackCallback; this._currentStatement = '#rollback'; return this._client.sqlBatch('IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION'); }; Connection.prototype.end = function() { this._autoCommit = true; this._pendingCallback = null; this._currentStatement = null; return this._client.end(); }; return Connection; })(EventEmitter); /** Statement class */ Statement = exports.Statement = (function(_super) { __extends(Statement, _super); function Statement(_connection, _sql, _params, handler) { this._connection = _connection; this._sql = _sql; this._params = _params; this.handler = handler; this._done = __bind(this._done, this); this._row = __bind(this._row, this); this._colmetadata = __bind(this._colmetadata, this); this._message = __bind(this._message, this); this._error = __bind(this._error, this); this.cancel = __bind(this.cancel, this); this.execute = __bind(this.execute, this); if (this._params != null) { this._parameterString = TdsUtils.buildParameterDefinition(this._params); } } Statement.prototype.prepare = function(cb) { var sql; if (this._preparedHandle != null) { throw new Error('Statement already prepared'); } if (!(this._parameterString != null) || this._parameterString === '') { throw new Error('Cannot prepare statement without parameters'); } if (this._connection._currentStatement != null) { throw new Error('Another statement already executing'); } this._connection._currentStatement = this; sql = "DECLARE @hndl Int;\nEXECUTE sp_prepare @hndl OUTPUT, N'" + this._parameterString + "',\nN'" + this._sql.replace(/'/g, "''") + "\n', 1;\nSELECT @hndl;"; this._pendingPrepareCallback = cb; return this._connection._client.sqlBatch(sql); }; Statement.prototype.unprepare = function(cb) { if (!(this._preparedHandle != null)) throw new Error('Statement not prepared'); if (this._connection._currentStatement != null) { throw new Error('Another statement already executing'); } this._connection._currentStatement = this; this._pendingUnprepareCallback = cb; return this._connection._client.sqlBatch('sp_unprepare ' + this._preparedHandle); }; Statement.prototype.execute = function(paramValues) { var sql; if (this._connection._currentStatement != null) { throw new Error('Another statement already executing'); } this._connection._currentStatement = this; sql = null; if (!(this._params != null) || this._parameterString === '') { sql = this._sql; } else if (this._preparedHandle != null) { sql = 'EXECUTE sp_execute ' + this._preparedHandle + ', ' + TdsUtils.buildParameterizedSql(this._params, paramValues); } else { if (!(this._parameterizedSql != null)) { this._parameterizedSql = "EXECUTE sp_executesql \nN'" + this._sql.replace(/'/g, "''") + "\n', N'" + this._parameterString + "'"; } sql = this._parameterizedSql + ', ' + TdsUtils.buildParameterizedSql(this._params, paramValues); } return this._connection._client.sqlBatch(sql); }; Statement.prototype.cancel = function() { if ((this._pendingPrepareCallback != null) || (this._pendingUnprepareCallback != null)) { throw new Error('Unable to cancel (un)prepare'); } this._cancelling = true; return this._connection._client.cancel(); }; Statement.prototype._error = function(err) { var cb, _base; if (this._pendingPrepareCallback != null) { cb = this._pendingPrepareCallback; this._pendingPrepareCallback = null; this._connection.currentStatement = null; cb(err); return this._ignoreNextDone = true; } else if (this._pendingUnprepareCallback != null) { cb = this._pendingUnprepareCallback; this._pendingUnprepareCallback = null; this._connection.currentStatement = null; cb(err); return this._ignoreNextDone = true; } else if (this.handler != null) { return typeof (_base = this.handler).error === "function" ? _base.error(err) : void 0; } else { return this.emit('error', err); } }; Statement.prototype._message = function(message) { var _base; if (this.handler != null) { return typeof (_base = this.handler).message === "function" ? _base.message(message) : void 0; } else { return this.emit('message', message); } }; Statement.prototype._colmetadata = function(colmetadata) { var _base; if (!this._cancelling && !(this._pendingPrepareCallback != null) && !(this._pendingUnprepareCallback != null)) { this.metadata = colmetadata; if (this.handler != null) { return typeof (_base = this.handler).metadata === "function" ? _base.metadata(this.metadata) : void 0; } else { return this.emit('metadata', this.metadata); } } }; Statement.prototype._row = function(row) { var _base; if (this._pendingPrepareCallback != null) { return this._preparedHandle = row.getValue(0); } else if (!this._cancelling) { if (this.handler != null) { return typeof (_base = this.handler).row === "function" ? _base.row(row) : void 0; } else { return this.emit('row', row); } } }; Statement.prototype._done = function(done) { var cb, _base; if (this._ignoreNextDone) { return this._ignoreNextDone = void 0; } else if (this._pendingPrepareCallback != null) { cb = this._pendingPrepareCallback; this._pendingPrepareCallback = null; this._connection._currentStatement = null; return cb(); } else if (this._pendingUnprepareCallback != null) { cb = this._pendingUnprepareCallback; this._pendingUnprepareCallback = null; this._preparedHandle = void 0; this._connection._currentStatement = null; return cb(); } else { if (this._cancelling) this._cancelling = void 0; this._connection._currentStatement = null; if (this.handler != null) { return typeof (_base = this.handler).done === "function" ? _base.done(done) : void 0; } else { return this.emit('done', done); } } }; return Statement; })(EventEmitter); /** TdsError class */ TdsError = exports.TdsError = (function(_super) { __extends(TdsError, _super); function TdsError(message, info) { this.message = message; this.info = info; this.name = 'TdsError'; this.stack = (new Error).stack; } return TdsError; })(Error);