| 145 | } |
| 146 | |
| 147 | function parse(x, state, parsers, handle, transform) { |
| 148 | const char = (acc, [k, v]) => (acc[k.charCodeAt(0)] = v, acc) |
| 149 | |
| 150 | Object.entries({ |
| 151 | R: x => { // Relation |
| 152 | let i = 1 |
| 153 | const r = state[x.readUInt32BE(i)] = { |
| 154 | schema: x.toString('utf8', i += 4, i = x.indexOf(0, i)) || 'pg_catalog', |
| 155 | table: x.toString('utf8', i + 1, i = x.indexOf(0, i + 1)), |
| 156 | columns: Array(x.readUInt16BE(i += 2)), |
| 157 | keys: [] |
| 158 | } |
| 159 | i += 2 |
| 160 | |
| 161 | let columnIndex = 0 |
| 162 | , column |
| 163 | |
| 164 | while (i < x.length) { |
| 165 | column = r.columns[columnIndex++] = { |
| 166 | key: x[i++], |
| 167 | name: transform.column.from |
| 168 | ? transform.column.from(x.toString('utf8', i, i = x.indexOf(0, i))) |
| 169 | : x.toString('utf8', i, i = x.indexOf(0, i)), |
| 170 | type: x.readUInt32BE(i += 1), |
| 171 | parser: parsers[x.readUInt32BE(i)], |
| 172 | atttypmod: x.readUInt32BE(i += 4) |
| 173 | } |
| 174 | |
| 175 | column.key && r.keys.push(column) |
| 176 | i += 4 |
| 177 | } |
| 178 | }, |
| 179 | Y: () => { /* noop */ }, // Type |
| 180 | O: () => { /* noop */ }, // Origin |
| 181 | B: x => { // Begin |
| 182 | state.date = Time(x.readBigInt64BE(9)) |
| 183 | state.lsn = x.subarray(1, 9) |
| 184 | }, |
| 185 | I: x => { // Insert |
| 186 | let i = 1 |
| 187 | const relation = state[x.readUInt32BE(i)] |
| 188 | const { row } = tuples(x, relation.columns, i += 7, transform) |
| 189 | |
| 190 | handle(row, { |
| 191 | command: 'insert', |
| 192 | relation |
| 193 | }) |
| 194 | }, |
| 195 | D: x => { // Delete |
| 196 | let i = 1 |
| 197 | const relation = state[x.readUInt32BE(i)] |
| 198 | i += 4 |
| 199 | const key = x[i] === 75 |
| 200 | handle(key || x[i] === 79 |
| 201 | ? tuples(x, relation.columns, i += 3, transform).row |
| 202 | : null |
| 203 | , { |
| 204 | command: 'delete', |