Do not use mysql command for setting up databases
This commit is contained in:
parent
b93afd4f9f
commit
873d88658c
7 changed files with 94 additions and 49 deletions
12
README.md
12
README.md
|
@ -28,17 +28,15 @@ Subscribe to Mailtrain Newsletter [here](http://mailtrain.org/subscription/EysIv
|
|||
1. Download Mailtrain files using git: `git clone git://github.com/andris9/mailtrain.git` and open Mailtrain folder `cd mailtrain`
|
||||
2. Run `npm install` in the Mailtrain folder to install required dependencies
|
||||
3. Copy [config/default.toml](config/default.toml) as `config/production.toml` and update MySQL and any other settings in it
|
||||
4. Import SQL tables by running `npm run sql` (invokes `mysql` command in the background, so you should have it installed. If you can't use this command, then you can import the [database file](setup/sql/mailtrain.sql) yourself). If MySQL configuration in config file is not correct then this command fails.
|
||||
5. Run the server `NODE_ENV=production npm start`
|
||||
6. Open [http://localhost:3000/](http://localhost:3000/)
|
||||
7. Authenticate as `admin`:`test`
|
||||
8. Navigate to [http://localhost:3000/settings](http://localhost:3000/settings) and update service configuration
|
||||
9. Navigate to [http://localhost:3000/users/account](http://localhost:3000/users/account) and update user information and password
|
||||
4. Run the server `NODE_ENV=production npm start`
|
||||
5. Open [http://localhost:3000/](http://localhost:3000/)
|
||||
6. Authenticate as `admin`:`test`
|
||||
7. Navigate to [http://localhost:3000/settings](http://localhost:3000/settings) and update service configuration
|
||||
8. Navigate to [http://localhost:3000/users/account](http://localhost:3000/users/account) and update user information and password
|
||||
|
||||
## Upgrade
|
||||
|
||||
* Replace old files with new ones by running in the Mailtrain folder `git pull origin master`
|
||||
* Upgrade MySQL tables by running `npm run sql`
|
||||
|
||||
## Using environment variables
|
||||
|
||||
|
|
19
index.js
19
index.js
|
@ -12,6 +12,7 @@ let sender = require('./services/sender');
|
|||
let importer = require('./services/importer'); // eslint-disable-line global-require
|
||||
let verpServer = require('./services/verp-server'); // eslint-disable-line global-require
|
||||
let testServer = require('./services/test-server'); // eslint-disable-line global-require
|
||||
let dbcheck = require('./lib/dbcheck');
|
||||
|
||||
let port = config.www.port;
|
||||
let host = config.www.host;
|
||||
|
@ -29,11 +30,19 @@ app.set('port', port);
|
|||
|
||||
let server = http.createServer(app);
|
||||
|
||||
/**
|
||||
|
||||
// Check if database needs upgrading before starting the server
|
||||
dbcheck(err => {
|
||||
if (err) {
|
||||
log.error('DB', err);
|
||||
return process.exit(1);
|
||||
}
|
||||
/**
|
||||
* Listen on provided port, on all network interfaces.
|
||||
*/
|
||||
server.listen(port, host);
|
||||
});
|
||||
|
||||
server.listen(port, host);
|
||||
|
||||
server.on('error', err => {
|
||||
if (err.syscall !== 'listen') {
|
||||
|
@ -46,12 +55,10 @@ server.on('error', err => {
|
|||
switch (err.code) {
|
||||
case 'EACCES':
|
||||
log.error('Express', '%s requires elevated privileges', bind);
|
||||
process.exit(1);
|
||||
break;
|
||||
return process.exit(1);
|
||||
case 'EADDRINUSE':
|
||||
log.error('Express', '%s is already in use', bind);
|
||||
process.exit(1);
|
||||
break;
|
||||
return process.exit(1);
|
||||
default:
|
||||
throw err;
|
||||
}
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
|
||||
let config = require('config');
|
||||
let mysql = require('mysql');
|
||||
let db = require('../../lib/db');
|
||||
let spawn = require('child_process').spawn;
|
||||
let settings = require('../../lib/models/settings');
|
||||
let log = require('npmlog');
|
||||
let fs = require('fs');
|
||||
let pathlib = require('path');
|
||||
let Handlebars = require('handlebars');
|
||||
let meta = require('../meta.json');
|
||||
|
||||
log.level = 'verbose';
|
||||
let mysqlConfig = {
|
||||
multipleStatements: true
|
||||
};
|
||||
Object.keys(config.mysql).forEach(key => mysqlConfig[key] = config.mysql[key]);
|
||||
let db = mysql.createPool(mysqlConfig);
|
||||
|
||||
function listTables(callback) {
|
||||
db.getConnection((err, connection) => {
|
||||
|
@ -49,21 +51,26 @@ function listTables(callback) {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
function getSchemaVersion(callback) {
|
||||
settings.list(['db_schema_version'], (err, configItems) => {
|
||||
db.getConnection((err, connection) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
connection.query('SELECT `value` FROM `settings` WHERE `key`=?', ['db_schema_version'], (err, rows) => {
|
||||
connection.release();
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
let dbSchemaVersion = Number(configItems.dbSchemaVersion) || 0;
|
||||
|
||||
let dbSchemaVersion = rows && rows[0] && Number(rows[0].value) || 0;
|
||||
callback(null, dbSchemaVersion);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function listUpdates(current, callback) {
|
||||
current = current || 0;
|
||||
fs.readdir(__dirname, (err, list) => {
|
||||
fs.readdir(pathlib.join(__dirname, '..', 'setup', 'sql'), (err, list) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
@ -75,7 +82,7 @@ function listUpdates(current, callback) {
|
|||
if (seq > current) {
|
||||
updates.push({
|
||||
seq: Number(seq),
|
||||
path: pathlib.join(__dirname, row)
|
||||
path: pathlib.join(__dirname, '..', 'setup', 'sql', row)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -96,21 +103,27 @@ function getSql(path, data, callback) {
|
|||
}
|
||||
|
||||
function runInitial(callback) {
|
||||
let path = pathlib.join(__dirname, process.env.FROM_START ? 'base.sql' : 'mailtrain.sql');
|
||||
let fname = process.env.DB_FROM_START ? 'base.sql' : 'mailtrain.sql';
|
||||
let path = pathlib.join(__dirname, '..', 'setup', 'sql', fname);
|
||||
log.info('sql', 'Loading tables from %s', fname);
|
||||
applyUpdate({
|
||||
path
|
||||
}, callback);
|
||||
}
|
||||
|
||||
function runUpdates(callback) {
|
||||
function runUpdates(callback, runCount) {
|
||||
runCount = Number(runCount) || 0;
|
||||
listTables((err, tables) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if (!tables.settings) {
|
||||
if (runCount) {
|
||||
return callback(new Error('Settings table not found from database'));
|
||||
}
|
||||
log.info('sql', 'SQL not set up, initializing');
|
||||
return runInitial(callback);
|
||||
return runInitial(runUpdates.bind(null, callback, ++runCount));
|
||||
}
|
||||
|
||||
getSchemaVersion((err, schemaVersion) => {
|
||||
|
@ -118,6 +131,11 @@ function runUpdates(callback) {
|
|||
return callback(err);
|
||||
}
|
||||
|
||||
if (schemaVersion >= meta.schemaVersion) {
|
||||
// nothing to do here, already updated
|
||||
return callback(null, false);
|
||||
}
|
||||
|
||||
listUpdates(schemaVersion, (err, updates) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
|
@ -159,26 +177,31 @@ function applyUpdate(update, callback) {
|
|||
return callback(err);
|
||||
}
|
||||
|
||||
let cmd = spawn(config.mysql.command || 'mysql', ['-h', config.mysql.host || 'localhost', '-P', config.mysql.port || 3306, '-u', config.mysql.user, '-p' + config.mysql.password, '-D', config.mysql.database]);
|
||||
|
||||
cmd.stdout.pipe(process.stdout);
|
||||
cmd.stderr.pipe(process.stderr);
|
||||
|
||||
cmd.on('close', code => {
|
||||
if (code) {
|
||||
return callback(new Error('mysql command exited with code ' + code));
|
||||
db.getConnection((err, connection) => {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
connection.query(sql, err => {
|
||||
connection.release();
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
return callback(null, true);
|
||||
});
|
||||
cmd.stdin.end(sql);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
runUpdates(err => {
|
||||
module.exports = callback => {
|
||||
runUpdates(err => {
|
||||
if (err) {
|
||||
log.error('sql', err);
|
||||
process.exit(1);
|
||||
return callback(err);
|
||||
}
|
||||
db.end(() => {
|
||||
log.info('sql', 'Database check completed');
|
||||
process.exit(0);
|
||||
});
|
||||
return callback(null, true);
|
||||
});
|
||||
});
|
||||
};
|
3
meta.json
Normal file
3
meta.json
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"schemaVersion": 1
|
||||
}
|
|
@ -6,8 +6,8 @@
|
|||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "grunt",
|
||||
"start": "node setup/sql/sql.js && node index.js",
|
||||
"sql": "node setup/sql/sql.js",
|
||||
"start": "node index.js",
|
||||
"sqlinit": "node setup/sql/init.js",
|
||||
"sqldump": "node setup/sql/dump.js | sed -e '/^--.*$/d' > setup/sql/mailtrain.sql",
|
||||
"sqldrop": "node setup/sql/drop.js"
|
||||
},
|
||||
|
|
14
setup/sql/init.js
Normal file
14
setup/sql/init.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
let dbcheck = require('../../lib/dbcheck');
|
||||
let log = require('npmlog');
|
||||
|
||||
log.level = 'verbose';
|
||||
|
||||
dbcheck(err => {
|
||||
if (err) {
|
||||
log.error('DB', err);
|
||||
return process.exit(1);
|
||||
}
|
||||
return process.exit(0);
|
||||
});
|
|
@ -221,7 +221,7 @@ CREATE TABLE `users` (
|
|||
KEY `check_reset` (`username`(191),`reset_token`,`reset_expire`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
LOCK TABLES `settings` WRITE;
|
||||
LOCK TABLES `users` WRITE;
|
||||
INSERT INTO `users` VALUES (1,'admin','$2a$10$mzKU71G62evnGB2PvQA4k..Wf9jASk.c7a8zRMHh6qQVjYJ2r/g/K','admin@example.com',NULL,NULL,'2016-04-20 17:20:48');
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
|
Loading…
Reference in a new issue