UNPKG

hsd

Version:
138 lines (106 loc) 2.99 kB
/** * migrations/state.js - migration state for hsd. * Copyright (c) 2021, Nodari Chkuaselidze (MIT License) */ 'use strict'; const assert = require('bsert'); const bio = require('bufio'); const {encoding} = bio; /** @typedef {import('../types').BufioWriter} BufioWriter */ const EMPTY = Buffer.alloc(0); /** * State of database migrations. * Because migration IDs are only increasing, we only need * to store the last one. * @alias module.migrations.MigrationState * @property {Boolean} inProgress - is/was migration in progress * NOTE: If inProgress is true, we know lastMigration + 1 was the one in * progress. * @property {Number} lastMigration - last migration * NOTE: Migration numbers start from 1. * 0 - means there is no migration. */ class MigrationState extends bio.Struct { /** * Create MigrationState * @constructor */ constructor() { super(); this.version = 1; this.inProgress = false; this.nextMigration = 0; /** @type {Number[]} */ this.skipped = []; this.inProgressData = EMPTY; } get lastMigration() { return this.nextMigration - 1; } /** * Inject properties from another state. * @param {MigrationState} obj * @returns MigrationState; */ inject(obj) { assert(obj instanceof MigrationState); this.inProgress = obj.inProgress; this.nextMigration = obj.nextMigration; this.skipped = obj.skipped.slice(); this.inProgressData = obj.inProgressData.slice(); return this; } /** * Get size of the encoded migration state object. * @returns {Number} */ getSize() { let size = 2; // flags size += 2; // version size += encoding.sizeVarint(this.nextMigration); size += encoding.sizeVarint(this.skipped.length); for (const id of this.skipped) size += encoding.sizeVarint(id); if (this.version > 0) size += encoding.sizeVarBytes(this.inProgressData); return size; } /** * Serialize migration state. * @param {BufioWriter} bw * @returns {BufioWriter} */ write(bw) { let flags = 0; if (this.inProgress) flags |= 1 << 0; bw.writeU16(flags); bw.writeU16(this.version); bw.writeVarint(this.nextMigration); bw.writeVarint(this.skipped.length); for (const id of this.skipped) bw.writeVarint(id); if (this.version > 0) bw.writeVarBytes(this.inProgressData); return bw; } /** * Deserialize migration state. * @param {bio.BufferReader} br * @returns {this} */ read(br) { const flags = br.readU16(); this.inProgress = (flags & 1) !== 0; this.version = br.readU16(); this.nextMigration = br.readVarint(); this.skipped = []; const skippedItems = br.readVarint(); for (let i = 0; i < skippedItems; i++) this.skipped.push(br.readVarint()); if (this.version > 0) this.inProgressData = br.readVarBytes(); return this; } } module.exports = MigrationState;