117 lines
2.4 KiB
JavaScript
117 lines
2.4 KiB
JavaScript
/**
|
|
* 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;
|
|
|
|
/**
|
|
* 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.inProgress = false;
|
|
this.nextMigration = 0;
|
|
this.skipped = [];
|
|
}
|
|
|
|
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();
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Get size of the encoded migration state object.
|
|
* @returns {Number}
|
|
*/
|
|
|
|
getSize() {
|
|
// flags + last migration number
|
|
let size = 4; // flags
|
|
size += encoding.sizeVarint(this.nextMigration);
|
|
size += encoding.sizeVarint(this.skipped.length);
|
|
|
|
for (const id of this.skipped)
|
|
size += encoding.sizeVarint(id);
|
|
|
|
return size;
|
|
}
|
|
|
|
/**
|
|
* Serialize migration state.
|
|
* @param {BufferWriter} bw
|
|
* @returns {BufferWriter}
|
|
*/
|
|
|
|
write(bw) {
|
|
let flags = 0;
|
|
|
|
if (this.inProgress)
|
|
flags |= 1 << 0;
|
|
|
|
bw.writeU32(flags);
|
|
bw.writeVarint(this.nextMigration);
|
|
bw.writeVarint(this.skipped.length);
|
|
|
|
for (const id of this.skipped)
|
|
bw.writeVarint(id);
|
|
|
|
return bw;
|
|
}
|
|
|
|
/**
|
|
* Deserialize migration state.
|
|
* @param {BufferReader}
|
|
* @returns {MigrationState}
|
|
*/
|
|
|
|
read(br) {
|
|
const flags = br.readU32();
|
|
|
|
this.inProgress = (flags & 1) !== 0;
|
|
this.nextMigration = br.readVarint();
|
|
this.skipped = [];
|
|
|
|
const skippedItems = br.readVarint();
|
|
|
|
for (let i = 0; i < skippedItems; i++)
|
|
this.skipped.push(br.readVarint(0));
|
|
|
|
return this;
|
|
}
|
|
}
|
|
|
|
module.exports = MigrationState;
|