text: 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);
          }
        },
        end: function() {
          var _base;
          if (_this.handler != null) {
            return typeof (_base = _this.handler).end === "function" ? _base.end() : void 0;
          } else {
            return _this.emit('end');
          }
        },
        close: function(had_error) {
          var _base;
          if (_this.handler != null) {
            return typeof (_base = _this.handler).close === "function" ? _base.close(had_error) : void 0;
          } else {
            return _this.emit('close', had_error);
          }
        }
      });
      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');
      this._client.debug('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);
  