UNPKG

apemandb

Version:
169 lines (152 loc) 4.23 kB
/** * Database for apeman. * @constructor Apemandb */ 'use strict' const argx = require('argx') const { singularize } = require('inflection') const { pascalcase } = require('stringcase') const co = require('co') const asleep = require('asleep') const deleteEmptyProps = require('./helpers/delete_empty_props') const prepareStorage = require('./storaging/prepare_storage') const TransactionExtension = require('./extensions/transaction_extension') const Sequelize = require('sequelize') const setupDatabase = require('./preparing/setup_database') const debug = require('debug')('apeman:db') /** @lends Apemandb */ function Apemandb (database, username, password, options) { let args = argx(arguments) options = Object.assign({ logging: false }, args.pop('object') || {}) database = args.shift('string') || null username = args.shift('string') || null password = args.shift('string') || null const s = this debug(`database: ${database}`) debug(`username: ${username}`) debug(`password: ${password}`) debug(`options: ${JSON.stringify(options)}`) deleteEmptyProps(options) prepareStorage(options.storage) // noinspection Eslint s.__proto__ = new Sequelize(database, username, password, options) Object.assign(s, Apemandb.prototype) Object.assign(s, TransactionExtension) } Apemandb.prototype = { /** * Setup database * @param {string} [rootUsername] - Username of root * @param {string} [rootPassword] - Password of root */ setup (rootUsername, rootPassword) { const s = this let { config } = s return co(function * () { let dialect = s.getDialect() yield setupDatabase(dialect, rootUsername, rootPassword, config) }) }, /** * Define a model. * @param {string} name * @param {Object} attributes - Model attributes. * @param {Object} options - Optional settings. * @returns {Model} */ define (name, attributes, options) { let args = argx(arguments) name = args.shift('string') attributes = deleteEmptyProps(args.shift('object') || {}) options = deleteEmptyProps(args.shift('object') || {}) const s = this // noinspection Eslint return s.__proto__.define(name, attributes, options) }, /** * Get a model. * @param {string} name - Name of the model. * @returns {Model} * @throws {Error} - Throw when not found. */ model (name) { const s = this let keys = Object.keys(s.models || {}) let _formatName = (name) => pascalcase(singularize(name)) for (let i = 0, len = keys.length; i < len; i++) { let hit = _formatName(keys[ i ]) === _formatName(name) if (hit) { return s.models[ keys[ i ] ] } } throw new Error('Model not found with name: ' + name) }, /** * Reset all tables. * @returns {Promise} */ reset () { const s = this let drop = () => co(function * () { return yield s.drop() }) let sync = () => co(function * () { return yield s.sync({ force: true }) }) return co(function * () { yield drop() yield sync() return s }) }, /** * Describe all tables. * @returns {Promise} */ describe () { const s = this let { models } = s let describe = (model) => co(function * () { return yield model.describe() }) return co(function * () { let result = {} for (let name of Object.keys(models || {})) { result[ name ] = yield describe(models[ name ]) } return result }) }, /** * Apply seed files. * @param {object} [options] - Optional settings. * @returns {Promise} */ seed (options) { const s = this let { seeds } = s let names = Object.keys(seeds) debug(`Seeding model names: ${names.join(', ')}`) return co(function * () { for (let name of names) { let seed = seeds[ name ] yield seed(s.model(name.replace(/^\d+\./, '')), options) yield asleep(10) } }) }, close () { const s = this return new Promise((resolve, reject) => { try { Sequelize.prototype.close.call(s) resolve() } catch (e) { reject(e) } }) } } module.exports = Apemandb