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