123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- 'use strict';
- const Types = require('../constants/types.js');
- const Charsets = require('../constants/charsets.js');
- const helpers = require('../helpers');
- const typeNames = [];
- for (const t in Types) {
- typeNames[Types[t]] = t;
- }
- function readField({ packet, type, charset, encoding, config, options }) {
- const supportBigNumbers = Boolean(
- options.supportBigNumbers || config.supportBigNumbers
- );
- const bigNumberStrings = Boolean(
- options.bigNumberStrings || config.bigNumberStrings
- );
- const timezone = options.timezone || config.timezone;
- const dateStrings = options.dateStrings || config.dateStrings;
- switch (type) {
- case Types.TINY:
- case Types.SHORT:
- case Types.LONG:
- case Types.INT24:
- case Types.YEAR:
- return packet.parseLengthCodedIntNoBigCheck();
- case Types.LONGLONG:
- if (supportBigNumbers && bigNumberStrings) {
- return packet.parseLengthCodedIntString();
- }
- return packet.parseLengthCodedInt(supportBigNumbers);
- case Types.FLOAT:
- case Types.DOUBLE:
- return packet.parseLengthCodedFloat();
- case Types.NULL:
- case Types.DECIMAL:
- case Types.NEWDECIMAL:
- if (config.decimalNumbers) {
- return packet.parseLengthCodedFloat();
- }
- return packet.readLengthCodedString('ascii');
- case Types.DATE:
- if (helpers.typeMatch(type, dateStrings, Types)) {
- return packet.readLengthCodedString('ascii');
- }
- return packet.parseDate(timezone);
- case Types.DATETIME:
- case Types.TIMESTAMP:
- if (helpers.typeMatch(type, dateStrings, Types)) {
- return packet.readLengthCodedString('ascii');
- }
- return packet.parseDateTime(timezone);
- case Types.TIME:
- return packet.readLengthCodedString('ascii');
- case Types.GEOMETRY:
- return packet.parseGeometryValue();
- case Types.VECTOR:
- return packet.parseVector();
- case Types.JSON:
- // Since for JSON columns mysql always returns charset 63 (BINARY),
- // we have to handle it according to JSON specs and use "utf8",
- // see https://github.com/sidorares/node-mysql2/issues/409
- return config.jsonStrings
- ? packet.readLengthCodedString('utf8')
- : JSON.parse(packet.readLengthCodedString('utf8'));
- default:
- if (charset === Charsets.BINARY) {
- return packet.readLengthCodedBuffer();
- }
- return packet.readLengthCodedString(encoding);
- }
- }
- function createTypecastField(field, packet) {
- return {
- type: typeNames[field.columnType],
- length: field.columnLength,
- db: field.schema,
- table: field.table,
- name: field.name,
- string: function (encoding = field.encoding) {
- if (field.columnType === Types.JSON && encoding === field.encoding) {
- // Since for JSON columns mysql always returns charset 63 (BINARY),
- // we have to handle it according to JSON specs and use "utf8",
- // see https://github.com/sidorares/node-mysql2/issues/1661
- console.warn(
- `typeCast: JSON column "${field.name}" is interpreted as BINARY by default, recommended to manually set utf8 encoding: \`field.string("utf8")\``
- );
- }
- return packet.readLengthCodedString(encoding);
- },
- buffer: function () {
- return packet.readLengthCodedBuffer();
- },
- geometry: function () {
- return packet.parseGeometryValue();
- },
- };
- }
- function getTextParser(_fields, _options, config) {
- return {
- next(packet, fields, options) {
- const result = options.rowsAsArray ? [] : {};
- for (let i = 0; i < fields.length; i++) {
- const field = fields[i];
- const typeCast = options.typeCast ? options.typeCast : config.typeCast;
- const next = () =>
- readField({
- packet,
- type: field.columnType,
- encoding: field.encoding,
- charset: field.characterSet,
- config,
- options,
- });
- let value;
- if (options.typeCast === false) {
- value = packet.readLengthCodedBuffer();
- } else if (typeof typeCast === 'function') {
- value = typeCast(createTypecastField(field, packet), next);
- } else {
- value = next();
- }
- if (options.rowsAsArray) {
- result.push(value);
- } else if (typeof options.nestTables === 'string') {
- result[
- `${helpers.fieldEscape(field.table, false)}${options.nestTables}${helpers.fieldEscape(field.name, false)}`
- ] = value;
- } else if (options.nestTables) {
- const tableName = helpers.fieldEscape(field.table, false);
- if (!result[tableName]) {
- result[tableName] = {};
- }
- result[tableName][helpers.fieldEscape(field.name, false)] = value;
- } else {
- result[helpers.fieldEscape(field.name, false)] = value;
- }
- }
- return result;
- },
- };
- }
- module.exports = getTextParser;
|