"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
exports.readCollation = readCollation;
exports.readMetadata = readMetadata;
var _collation = require("./collation");
var _dataType = require("./data-type");
var _sprintfJs = require("sprintf-js");
var _helpers = require("./token/helpers");
function readCollation(buf, offset) {
  offset = +offset;
  if (buf.length < offset + 5) {
    throw new _helpers.NotEnoughDataError(offset + 5);
  }
  const collation = _collation.Collation.fromBuffer(buf.slice(offset, offset + 5));
  return new _helpers.Result(collation, offset + 5);
}
function readSchema(buf, offset) {
  offset = +offset;
  let schemaPresent;
  ({
    offset,
    value: schemaPresent
  } = (0, _helpers.readUInt8)(buf, offset));
  if (schemaPresent !== 0x01) {
    return new _helpers.Result(undefined, offset);
  }
  let dbname;
  ({
    offset,
    value: dbname
  } = (0, _helpers.readBVarChar)(buf, offset));
  let owningSchema;
  ({
    offset,
    value: owningSchema
  } = (0, _helpers.readBVarChar)(buf, offset));
  let xmlSchemaCollection;
  ({
    offset,
    value: xmlSchemaCollection
  } = (0, _helpers.readUsVarChar)(buf, offset));
  return new _helpers.Result({
    dbname,
    owningSchema,
    xmlSchemaCollection
  }, offset);
}
function readUDTInfo(buf, offset) {
  let maxByteSize;
  ({
    offset,
    value: maxByteSize
  } = (0, _helpers.readUInt16LE)(buf, offset));
  let dbname;
  ({
    offset,
    value: dbname
  } = (0, _helpers.readBVarChar)(buf, offset));
  let owningSchema;
  ({
    offset,
    value: owningSchema
  } = (0, _helpers.readBVarChar)(buf, offset));
  let typeName;
  ({
    offset,
    value: typeName
  } = (0, _helpers.readBVarChar)(buf, offset));
  let assemblyName;
  ({
    offset,
    value: assemblyName
  } = (0, _helpers.readUsVarChar)(buf, offset));
  return new _helpers.Result({
    maxByteSize: maxByteSize,
    dbname: dbname,
    owningSchema: owningSchema,
    typeName: typeName,
    assemblyName: assemblyName
  }, offset);
}
function readMetadata(buf, offset, options) {
  let userType;
  ({
    offset,
    value: userType
  } = (options.tdsVersion < '7_2' ? _helpers.readUInt16LE : _helpers.readUInt32LE)(buf, offset));
  let flags;
  ({
    offset,
    value: flags
  } = (0, _helpers.readUInt16LE)(buf, offset));
  let typeNumber;
  ({
    offset,
    value: typeNumber
  } = (0, _helpers.readUInt8)(buf, offset));
  const type = _dataType.TYPE[typeNumber];
  if (!type) {
    throw new Error((0, _sprintfJs.sprintf)('Unrecognised data type 0x%02X', typeNumber));
  }
  switch (type.name) {
    case 'Null':
    case 'TinyInt':
    case 'SmallInt':
    case 'Int':
    case 'BigInt':
    case 'Real':
    case 'Float':
    case 'SmallMoney':
    case 'Money':
    case 'Bit':
    case 'SmallDateTime':
    case 'DateTime':
    case 'Date':
      return new _helpers.Result({
        userType: userType,
        flags: flags,
        type: type,
        collation: undefined,
        precision: undefined,
        scale: undefined,
        dataLength: undefined,
        schema: undefined,
        udtInfo: undefined
      }, offset);
    case 'IntN':
    case 'FloatN':
    case 'MoneyN':
    case 'BitN':
    case 'UniqueIdentifier':
    case 'DateTimeN':
      {
        let dataLength;
        ({
          offset,
          value: dataLength
        } = (0, _helpers.readUInt8)(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: undefined,
          precision: undefined,
          scale: undefined,
          dataLength: dataLength,
          schema: undefined,
          udtInfo: undefined
        }, offset);
      }
    case 'Variant':
      {
        let dataLength;
        ({
          offset,
          value: dataLength
        } = (0, _helpers.readUInt32LE)(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: undefined,
          precision: undefined,
          scale: undefined,
          dataLength: dataLength,
          schema: undefined,
          udtInfo: undefined
        }, offset);
      }
    case 'VarChar':
    case 'Char':
    case 'NVarChar':
    case 'NChar':
      {
        let dataLength;
        ({
          offset,
          value: dataLength
        } = (0, _helpers.readUInt16LE)(buf, offset));
        let collation;
        ({
          offset,
          value: collation
        } = readCollation(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: collation,
          precision: undefined,
          scale: undefined,
          dataLength: dataLength,
          schema: undefined,
          udtInfo: undefined
        }, offset);
      }
    case 'Text':
    case 'NText':
      {
        let dataLength;
        ({
          offset,
          value: dataLength
        } = (0, _helpers.readUInt32LE)(buf, offset));
        let collation;
        ({
          offset,
          value: collation
        } = readCollation(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: collation,
          precision: undefined,
          scale: undefined,
          dataLength: dataLength,
          schema: undefined,
          udtInfo: undefined
        }, offset);
      }
    case 'VarBinary':
    case 'Binary':
      {
        let dataLength;
        ({
          offset,
          value: dataLength
        } = (0, _helpers.readUInt16LE)(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: undefined,
          precision: undefined,
          scale: undefined,
          dataLength: dataLength,
          schema: undefined,
          udtInfo: undefined
        }, offset);
      }
    case 'Image':
      {
        let dataLength;
        ({
          offset,
          value: dataLength
        } = (0, _helpers.readUInt32LE)(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: undefined,
          precision: undefined,
          scale: undefined,
          dataLength: dataLength,
          schema: undefined,
          udtInfo: undefined
        }, offset);
      }
    case 'Xml':
      {
        let schema;
        ({
          offset,
          value: schema
        } = readSchema(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: undefined,
          precision: undefined,
          scale: undefined,
          dataLength: undefined,
          schema: schema,
          udtInfo: undefined
        }, offset);
      }
    case 'Time':
    case 'DateTime2':
    case 'DateTimeOffset':
      {
        let scale;
        ({
          offset,
          value: scale
        } = (0, _helpers.readUInt8)(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: undefined,
          precision: undefined,
          scale: scale,
          dataLength: undefined,
          schema: undefined,
          udtInfo: undefined
        }, offset);
      }
    case 'NumericN':
    case 'DecimalN':
      {
        let dataLength;
        ({
          offset,
          value: dataLength
        } = (0, _helpers.readUInt8)(buf, offset));
        let precision;
        ({
          offset,
          value: precision
        } = (0, _helpers.readUInt8)(buf, offset));
        let scale;
        ({
          offset,
          value: scale
        } = (0, _helpers.readUInt8)(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: undefined,
          precision: precision,
          scale: scale,
          dataLength: dataLength,
          schema: undefined,
          udtInfo: undefined
        }, offset);
      }
    case 'UDT':
      {
        let udtInfo;
        ({
          offset,
          value: udtInfo
        } = readUDTInfo(buf, offset));
        return new _helpers.Result({
          userType: userType,
          flags: flags,
          type: type,
          collation: undefined,
          precision: undefined,
          scale: undefined,
          dataLength: undefined,
          schema: undefined,
          udtInfo: udtInfo
        }, offset);
      }
    default:
      throw new Error((0, _sprintfJs.sprintf)('Unrecognised type %s', type.name));
  }
}
function metadataParse(parser, options, callback) {
  (async () => {
    while (true) {
      let result;
      try {
        result = readMetadata(parser.buffer, parser.position, options);
      } catch (err) {
        if (err instanceof _helpers.NotEnoughDataError) {
          await parser.waitForChunk();
          continue;
        }
        throw err;
      }
      parser.position = result.offset;
      return callback(result.value);
    }
  })();
}
var _default = exports.default = metadataParse;
module.exports = metadataParse;
module.exports.readCollation = readCollation;
module.exports.readMetadata = readMetadata;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,[encoded data, 25140 characters]