/** * Configure our database. * @module app/db/configure */ import _knex from "knex"; import _bookshelf from "bookshelf"; import jsonColumns from "bookshelf-json-columns"; import cascadeDelete from "bookshelf-cascade-delete"; import { knexfile } from "app/constants"; import { registerModels } from "app/db/models"; import { types } from "pg"; /** * PostgreSQL type conversion */ types.setTypeParser(types.builtins.INT8, (value) => parseInt(value)); types.setTypeParser(types.builtins.FLOAT8, (value) => parseFloat(value)); types.setTypeParser(types.builtins.NUMERIC, (value) => parseFloat(value)); /** * Memoized copies of the current knex and bookshelf objects. */ let knex, bookshelf; /** * Configure a knex instance based on the knexfile. */ function configureKnex() { const environment = process.env.NODE_ENV ?? "development"; if (!knexfile[environment]) { throw new Error("Please specify a valid NODE_ENV"); } knex = _knex(knexfile[environment]); return knex; } /** * Configure knex and bookshelf. By default, memoizes the * knex object so other methods can call `configure()` and get it. * The database is configured this way to be interoperable with the test environment. * * @param {Object} __knex An existing knex instance, mainly used in testing. */ export default function configure(__knex) { if (!knex || (__knex && knex !== __knex)) { knex = __knex || configureKnex(); bookshelf = _bookshelf(knex); bookshelf.plugin(jsonColumns); bookshelf.plugin(cascadeDelete); registerModels(bookshelf); } return { bookshelf, knex }; }