UNPKG

@sangaman/xud

Version:
149 lines 7.36 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) t[p[i]] = s[p[i]]; return t; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = __importDefault(require("fs")); const path_1 = __importDefault(require("path")); const assert_1 = __importDefault(require("assert")); const sequelize_1 = __importDefault(require("sequelize")); const enums_1 = require("../types/enums"); /** A class representing a connection to a SQL database. */ class DB { constructor(config, logger) { this.config = config; this.logger = logger; this.init = () => __awaiter(this, void 0, void 0, function* () { let newDb = false; try { yield this.sequelize.authenticate(); const { host, port, database } = this.config; this.logger.info(`connected to database. host:${host} port:${port} database:${database}`); } catch (err) { if (DB.isDbDoesNotExistError(err)) { newDb = true; yield this.createDatabase(); } else { this.logger.error('unable to connect to the database', err); throw err; } } const { Node, Currency, Pair } = this.models; const options = { logging: this.logger.verbose }; // sync schemas with the database in phases, according to FKs dependencies yield Promise.all([ Node.sync(options), Currency.sync(options), ]); yield Promise.all([ Pair.sync(options), ]); if (newDb) { // populate new databases with default data // TODO: make seed peers configurable yield Node.bulkCreate([ { nodePubKey: '02b66438730d1fcdf4a4ae5d3d73e847a272f160fee2938e132b52cab0a0d9cfc6', addresses: [{ host: 'xud1.test.exchangeunion.com', port: 8885 }], }, { nodePubKey: '028599d05b18c0c3f8028915a17d603416f7276c822b6b2d20e71a3502bd0f9e0a', addresses: [{ host: 'xud2.test.exchangeunion.com', port: 8885 }], }, { nodePubKey: '03fd337659e99e628d0487e4f87acf93e353db06f754dccc402f2de1b857a319d0', addresses: [{ host: 'xud3.test.exchangeunion.com', port: 8885 }], }, ]); yield Currency.bulkCreate([ { id: 'BTC' }, { id: 'LTC' }, { id: 'ZRX' }, { id: 'GNT' }, ]); yield Pair.bulkCreate([ { baseCurrency: 'BTC', quoteCurrency: 'LTC', swapProtocol: enums_1.SwapProtocol.LND }, { baseCurrency: 'ZRX', quoteCurrency: 'GNT', swapProtocol: enums_1.SwapProtocol.RAIDEN }, ]); } }); this.close = () => { return this.sequelize.close(); }; this.dropTables = () => { return this.sequelize.drop(); }; this.truncate = () => __awaiter(this, void 0, void 0, function* () { yield this.sequelize.transaction((t) => __awaiter(this, void 0, void 0, function* () { const options = { raw: true, transaction: t }; yield this.sequelize.query('SET FOREIGN_KEY_CHECKS = 0', options); yield this.sequelize.query('truncate table pairs', options); yield this.sequelize.query('truncate table currencies', options); yield this.sequelize.query('truncate table nodes', options); yield this.sequelize.query('SET FOREIGN_KEY_CHECKS = 1', options); })); }); this.createSequelizeInstance = (config) => { return new sequelize_1.default(Object.assign({}, config, { dialect: 'mysql', operatorsAliases: false, dialectOptions: { multipleStatements: true, } })); }; this.loadModels = () => { const models = {}; const modelsFolder = path_1.default.join(__dirname, 'models'); fs_1.default.readdirSync(modelsFolder) .filter(file => (file.indexOf('.') !== 0) && (file !== path_1.default.basename(__filename)) && (file.slice(-3).match(/.js|.ts/))) .forEach((file) => { const model = this.sequelize.import(path_1.default.join(modelsFolder, file)); models[model.name] = model; }); Object.keys(models).forEach((key) => { const model = models[key]; if (model.associate) { model.associate(models); } }); return models; }; this.createDatabase = () => __awaiter(this, void 0, void 0, function* () { try { const _a = this.config, { database } = _a, databaselessConfig = __rest(_a, ["database"]); const sequelize = this.createSequelizeInstance(databaselessConfig); yield sequelize.authenticate(); yield sequelize.query(`CREATE DATABASE ${database} CHARACTER SET utf8 COLLATE utf8_general_ci;`); yield sequelize.close(); } catch (err) { this.logger.error('unable to create the database', err); throw err; } }); assert_1.default(Number.isInteger(config.port) && config.port > 1023 && config.port < 65536, 'port must be an integer between 1024 and 65535'); this.sequelize = this.createSequelizeInstance(this.config); this.models = this.loadModels(); } static isDbDoesNotExistError(err) { return err instanceof sequelize_1.default.ConnectionError && err.original.code === 'ER_BAD_DB_ERROR'; } } exports.default = DB; //# sourceMappingURL=DB.js.map