binlog_query_statusvars.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. 'use strict';
  2. // http://dev.mysql.com/doc/internals/en/query-event.html
  3. const keys = {
  4. FLAGS2: 0,
  5. SQL_MODE: 1,
  6. CATALOG: 2,
  7. AUTO_INCREMENT: 3,
  8. CHARSET: 4,
  9. TIME_ZONE: 5,
  10. CATALOG_NZ: 6,
  11. LC_TIME_NAMES: 7,
  12. CHARSET_DATABASE: 8,
  13. TABLE_MAP_FOR_UPDATE: 9,
  14. MASTER_DATA_WRITTEN: 10,
  15. INVOKERS: 11,
  16. UPDATED_DB_NAMES: 12,
  17. MICROSECONDS: 3
  18. };
  19. module.exports = function parseStatusVars(buffer) {
  20. const result = {};
  21. let offset = 0;
  22. let key, length, prevOffset;
  23. while (offset < buffer.length) {
  24. key = buffer[offset++];
  25. switch (key) {
  26. case keys.FLAGS2:
  27. result.flags = buffer.readUInt32LE(offset);
  28. offset += 4;
  29. break;
  30. case keys.SQL_MODE:
  31. // value is 8 bytes, but all dcumented flags are in first 4 bytes
  32. result.sqlMode = buffer.readUInt32LE(offset);
  33. offset += 8;
  34. break;
  35. case keys.CATALOG:
  36. length = buffer[offset++];
  37. result.catalog = buffer.toString('utf8', offset, offset + length);
  38. offset += length + 1; // null byte after string
  39. break;
  40. case keys.CHARSET:
  41. result.clientCharset = buffer.readUInt16LE(offset);
  42. result.connectionCollation = buffer.readUInt16LE(offset + 2);
  43. result.serverCharset = buffer.readUInt16LE(offset + 4);
  44. offset += 6;
  45. break;
  46. case keys.TIME_ZONE:
  47. length = buffer[offset++];
  48. result.timeZone = buffer.toString('utf8', offset, offset + length);
  49. offset += length; // no null byte
  50. break;
  51. case keys.CATALOG_NZ:
  52. length = buffer[offset++];
  53. result.catalogNz = buffer.toString('utf8', offset, offset + length);
  54. offset += length; // no null byte
  55. break;
  56. case keys.LC_TIME_NAMES:
  57. result.lcTimeNames = buffer.readUInt16LE(offset);
  58. offset += 2;
  59. break;
  60. case keys.CHARSET_DATABASE:
  61. result.schemaCharset = buffer.readUInt16LE(offset);
  62. offset += 2;
  63. break;
  64. case keys.TABLE_MAP_FOR_UPDATE:
  65. result.mapForUpdate1 = buffer.readUInt32LE(offset);
  66. result.mapForUpdate2 = buffer.readUInt32LE(offset + 4);
  67. offset += 8;
  68. break;
  69. case keys.MASTER_DATA_WRITTEN:
  70. result.masterDataWritten = buffer.readUInt32LE(offset);
  71. offset += 4;
  72. break;
  73. case keys.INVOKERS:
  74. length = buffer[offset++];
  75. result.invokerUsername = buffer.toString(
  76. 'utf8',
  77. offset,
  78. offset + length
  79. );
  80. offset += length;
  81. length = buffer[offset++];
  82. result.invokerHostname = buffer.toString(
  83. 'utf8',
  84. offset,
  85. offset + length
  86. );
  87. offset += length;
  88. break;
  89. case keys.UPDATED_DB_NAMES:
  90. length = buffer[offset++];
  91. // length - number of null-terminated strings
  92. result.updatedDBs = []; // we'll store them as array here
  93. for (; length; --length) {
  94. prevOffset = offset;
  95. // fast forward to null terminating byte
  96. while (buffer[offset++] && offset < buffer.length) {
  97. // empty body, everything inside while condition
  98. }
  99. result.updatedDBs.push(
  100. buffer.toString('utf8', prevOffset, offset - 1)
  101. );
  102. }
  103. break;
  104. case keys.MICROSECONDS:
  105. result.microseconds =
  106. // REVIEW: INVALID UNKNOWN VARIABLE!
  107. buffer.readInt16LE(offset) + (buffer[offset + 2] << 16);
  108. offset += 3;
  109. }
  110. }
  111. return result;
  112. };