2019-01-17 22:24:09 +13:00

162 lines
5.4 KiB
JavaScript

'use strict';
/**
* Module dependencies
*/
// Node.js core.
const path = require('path');
// Public node modules.
const _ = require('lodash');
/* eslint-disable prefer-template */
// Array of supported clients.
const CLIENTS = [
'pg',
'mysql', 'mysql2',
'sqlite3',
'mariasql',
'oracle', 'strong-oracle',
'mssql'
];
/**
* Knex hook
*/
module.exports = strapi => {
const hook = {
/**
* Default options
*/
defaults: {
connection: {
host: 'localhost',
charset: 'utf8'
}
},
/**
* Initialize the hook
*/
initialize: cb => {
// For each connection in the config register a new Knex connection.
_.forEach(_.pickBy(strapi.config.connections, {connector: 'strapi-hook-bookshelf'}), (connection, name) => {
// Make sure we use the client even if the typo is not the exact one.
switch (connection.settings.client) {
case 'postgre':
case 'postgres':
case 'postgresql':
connection.settings.client = 'pg';
break;
case 'sqlite':
connection.settings.client = 'sqlite3';
break;
case 'maria':
case 'mariadb':
connection.settings.client = 'mariasql';
break;
case 'ms':
connection.settings.client = 'mssql';
break;
}
// Make sure the client is supported.
if (!_.includes(CLIENTS, connection.settings.client)) {
strapi.log.error('The client `' + connection.settings.client + '` for the `' + name + '` connection is not supported.');
strapi.stop();
}
// Make sure the client is installed in the application
// `node_modules` directory.
let client;
try {
client = require(path.resolve(strapi.config.appPath, 'node_modules', connection.settings.client));
} catch (err) {
strapi.log.error('The client `' + connection.settings.client + '` is not installed.');
strapi.log.error('You can install it with `$ npm install ' + connection.settings.client + ' --save`.');
strapi.stop();
}
const options = _.defaultsDeep({
client: connection.settings.client,
connection: {
host: _.get(connection.settings, 'host'),
user: _.get(connection.settings, 'username') || _.get(connection.settings, 'user'),
password: _.get(connection.settings, 'password'),
database: _.get(connection.settings, 'database'),
charset: _.get(connection.settings, 'charset'),
schema: _.get(connection.settings, 'schema', 'public'),
port: _.get(connection.settings, 'port'),
socket: _.get(connection.settings, 'socketPath'),
ssl: _.get(connection.settings, 'ssl', false),
timezone: _.get(connection.settings, 'timezone', 'utc'),
},
debug: _.get(connection.options, 'debug', false),
acquireConnectionTimeout: _.get(connection.options, 'acquireConnectionTimeout'),
migrations: _.get(connection.options, 'migrations')
}, strapi.config.hook.settings.knex);
options.pool = {
min: _.get(connection.options, 'pool.min', 0),
max: _.get(connection.options, 'pool.max', 10),
acquireTimeoutMillis: _.get(connection.options, 'pool.acquireTimeoutMillis', 2000),
createTimeoutMillis: _.get(connection.options, 'pool.createTimeoutMillis', 2000),
idleTimeoutMillis: _.get(connection.options, 'pool.idleTimeoutMillis', 30000),
reapIntervalMillis: _.get(connection.options, 'pool.reapIntervalMillis', 1000),
createRetryIntervalMillis: _.get(connection.options, 'pool.createRetryIntervalMillis', 200),
};
if (options.client === 'pg') {
client.types.setTypeParser(1700, 'text', parseFloat);
if (_.isString(_.get(options.connection, 'schema'))) {
options.pool = {
afterCreate: (conn, cb) => {
// conn.query(`SET SESSION SCHEMA '${options.connection.schema}';`, (err) => { // It seems the right way is the one below
conn.query(`SET search_path TO '${options.connection.schema}';`, (err) => {
cb(err, conn);
});
}
};
} else {
delete options.connection.schema;
}
}
if (options.client === 'mysql') {
options.connection.typeCast = (field, next) => {
if (field.type === 'TINY' && field.length === 1) {
return (field.string() === '1');
}
return next();
};
}
// Finally, use the client via `knex`.
// If anyone has a solution to use different paths for `knex` and clients
// please drop us an email at support@strapi.io-- it would avoid the Strapi
// applications to have `knex` as a dependency.
try {
// Try to require from local dependency.
_.set(strapi, `connections.${name}`, require(path.resolve(strapi.config.appPath, 'node_modules', 'knex'))(options));
} catch (err) {
strapi.log.error('Impossible to use the `' + name + '` connection...');
strapi.log.warn('Be sure that your client `' + name + '` are in the same node_modules directory');
strapi.log.error(err);
strapi.stop();
}
});
cb();
}
};
return hook;
};