// Generated by CoffeeScript 1.10.0
(function() {
  var JSON_COLUMN_ID, MAX, TYPES, Table, declare, ref,
    slice = [].slice;

  ref = require('./datatypes'), TYPES = ref.TYPES, declare = ref.declare;

  MAX = 65535;

  JSON_COLUMN_ID = 'JSON_F52E2B61-18A1-11d1-B105-00805F49916B';

  Table = (function() {
    function Table(name) {
      var ref1;
      if (name) {
        ref1 = Table.parseName(name), this.name = ref1.name, this.schema = ref1.schema, this.database = ref1.database;
        this.path = "" + (this.database ? "[" + this.database + "]." : "") + (this.schema ? "[" + this.schema + "]." : "") + "[" + this.name + "]";
        this.temporary = this.name.charAt(0) === '#';
      }
      this.columns = [];
      this.rows = [];
      Object.defineProperty(this.columns, "add", {
        value: function(name, column, options) {
          if (options == null) {
            options = {};
          }
          if (column == null) {
            throw new Error("Column data type is not defined.");
          }
          if (column instanceof Function) {
            column = column();
          }
          column.name = name;
          column.nullable = options.nullable;
          column.primary = options.primary;
          return this.push(column);
        }
      });
      Object.defineProperty(this.rows, "add", {
        value: function() {
          var values;
          values = 1 <= arguments.length ? slice.call(arguments, 0) : [];
          return this.push(values);
        }
      });
    }


    /*
    	@private
     */

    Table.prototype._makeBulk = function() {
      var col, i, len, ref1;
      ref1 = this.columns;
      for (i = 0, len = ref1.length; i < len; i++) {
        col = ref1[i];
        switch (col.type) {
          case TYPES.Xml:
            col.type = TYPES.NVarChar(MAX).type;
            break;
          case TYPES.UDT:
          case TYPES.Geography:
          case TYPES.Geometry:
            col.type = TYPES.VarBinary(MAX).type;
        }
      }
      return this;
    };

    Table.prototype.declare = function() {
      var cols, pkey;
      pkey = this.columns.filter(function(col) {
        return col.primary === true;
      }).map(function(col) {
        return col.name;
      });
      cols = this.columns.map(function(col) {
        var def;
        def = ["[" + col.name + "] " + (declare(col.type, col))];
        if (col.nullable === true) {
          def.push("null");
        } else if (col.nullable === false) {
          def.push("not null");
        }
        if (col.primary === true && pkey.length === 1) {
          def.push("primary key");
        }
        return def.join(' ');
      });
      return "create table " + this.path + " (" + (cols.join(', ')) + (pkey.length > 1 ? ", constraint PK_" + (this.temporary ? this.name.substr(1) : this.name) + " primary key (" + (pkey.join(', ')) + ")" : "") + ")";
    };

    Table.fromRecordset = function(recordset, name) {
      var col, i, j, len, len1, ref1, ref2, row, t;
      t = new this(name);
      ref1 = recordset.columns;
      for (name in ref1) {
        col = ref1[name];
        t.columns.add(name, {
          type: col.type,
          length: col.length,
          scale: col.scale,
          precision: col.precision
        }, {
          nullable: col.nullable
        });
      }
      if (t.columns.length === 1 && t.columns[0].name === JSON_COLUMN_ID) {
        for (i = 0, len = recordset.length; i < len; i++) {
          row = recordset[i];
          t.rows.add(JSON.stringify(row));
        }
      } else {
        for (j = 0, len1 = recordset.length; j < len1; j++) {
          row = recordset[j];
          (ref2 = t.rows).add.apply(ref2, (function() {
            var k, len2, ref2, results;
            ref2 = t.columns;
            results = [];
            for (k = 0, len2 = ref2.length; k < len2; k++) {
              col = ref2[k];
              results.push(row[col.name]);
            }
            return results;
          })());
        }
      }
      return t;
    };

    Table.parseName = function(name) {
      var buffer, char, cursor, escaped, length, path;
      length = name.length;
      cursor = -1;
      buffer = '';
      escaped = false;
      path = [];
      while (++cursor < length) {
        char = name.charAt(cursor);
        if (char === '[') {
          if (escaped) {
            buffer += char;
          } else {
            escaped = true;
          }
        } else if (char === ']') {
          if (escaped) {
            escaped = false;
          } else {
            throw new Error("Invalid table name.");
          }
        } else if (char === '.') {
          if (escaped) {
            buffer += char;
          } else {
            path.push(buffer);
            buffer = '';
          }
        } else {
          buffer += char;
        }
      }
      if (buffer) {
        path.push(buffer);
      }
      switch (path.length) {
        case 1:
          return {
            name: path[0],
            schema: null,
            database: null
          };
        case 2:
          return {
            name: path[1],
            schema: path[0],
            database: null
          };
        case 3:
          return {
            name: path[2],
            schema: path[1],
            database: path[0]
          };
        default:
          throw new Error("Invalid table name.");
      }
    };

    return Table;

  })();

  module.exports = Table;

}).call(this);
