compile_text_parser.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. var Types = require('./constants/types');
  2. var Charsets = require('./constants/charsets');
  3. var vm = require('vm');
  4. var srcEscape = require('./helpers').srcEscape;
  5. var typeNames = [];
  6. for (var t in Types) {
  7. typeNames[Types[t]] = t;
  8. }
  9. function compile(fields, options, config) {
  10. var result = [];
  11. var i=0;
  12. var lvalue = '';
  13. result.push('(function() { return function TextRow(packet) {');
  14. if (options.rowsAsArray)
  15. result.push(' var result = new Array(' + fields.length + ')');
  16. var resultTables = {};
  17. var resultTablesArray = [];
  18. if (options.nestTables === true) {
  19. for (i = 0; i < fields.length; i++) {
  20. resultTables[fields[i].table] = 1;
  21. }
  22. resultTablesArray = Object.keys(resultTables);
  23. for (i = 0; i < resultTablesArray.length; i++) {
  24. result.push(' this[' + srcEscape(resultTablesArray[i]) + '] = {};');
  25. }
  26. }
  27. var fieldName = '';
  28. var tableName = '';
  29. for (i = 0; i < fields.length; i++) {
  30. fieldName = srcEscape(fields[i].name);
  31. result.push(' // ' + fieldName + ': '+ typeNames[fields[i].columnType]);
  32. if (typeof options.nestTables == 'string') {
  33. tableName = srcEscape(fields[i].table);
  34. lvalue = [' this[', srcEscape(fields[i].table + options.nestTables + fields[i].name), ']'].join('');
  35. } else if (options.nestTables === true) {
  36. tableName = srcEscape(fields[i].table);
  37. lvalue = [' this[', tableName, '][', fieldName, ']'].join('');
  38. } else if (options.rowsAsArray) {
  39. lvalue = ' result[' + i.toString(10) + ']';
  40. } else
  41. lvalue = ' this[' + srcEscape(fields[i].name) + ']';
  42. result.push(lvalue + ' = ' + readCodeFor(fields[i].columnType, fields[i].characterSet, config));
  43. }
  44. if (options.rowsAsArray)
  45. result.push(' return result;');
  46. result.push('};})()');
  47. var src = result.join('\n');
  48. if (config.debug) {
  49. console.log(' Compiled text protocol row parser:\n\n');
  50. var cardinal = require('cardinal');
  51. console.log(cardinal.highlight(src) + '\n\n');
  52. }
  53. return vm.runInThisContext(src);
  54. }
  55. function readCodeFor(type, charset, config) {
  56. switch(type) {
  57. case Types.TINY:
  58. case Types.SHORT:
  59. case Types.LONG:
  60. case Types.INT24:
  61. case Types.YEAR:
  62. case Types.LONG:
  63. return "packet.parseLengthCodedInt();";
  64. case Types.LONGLONG:
  65. if (config.supportBigNumbers && config.bigNumberStrings) {
  66. return "packet.parseLengthCodedIntString();";
  67. }
  68. return "packet.parseLengthCodedInt();";
  69. case Types.FLOAT:
  70. case Types.DOUBLE:
  71. return "packet.parseLengthCodedFloat();";
  72. case Types.NULL:
  73. return "null; packet.skip(1);";
  74. case Types.DECIMAL:
  75. case Types.NEWDECIMAL:
  76. return "packet.readLengthCodedString(); //" + type + ' ' + charset;
  77. case Types.DATE:
  78. if (config.dateStrings)
  79. return "packet.readLengthCodedString()";
  80. return "packet.parseDate();";
  81. case Types.DATETIME:
  82. case Types.TIMESTAMP:
  83. if (config.dateStrings)
  84. return "packet.readLengthCodedString()";
  85. return "packet.parseDateTime();";
  86. case Types.TIME:
  87. return "packet.readLengthCodedString()";
  88. case Types.GEOMETRY:
  89. return "packet.parseGeometryValue();";
  90. default:
  91. if (charset == Charsets.BINARY)
  92. return "packet.readLengthCodedBuffer();";
  93. else
  94. return "packet.readLengthCodedString(); //" + type + ' ' + charset;
  95. }
  96. }
  97. module.exports = compile;