2016-03-07 09:30:43 -08:00
|
|
|
'use strict';
|
|
|
|
|
|
|
|
|
|
var assert = require('assert'),
|
|
|
|
|
database = require('./database.js'),
|
|
|
|
|
DatabaseError = require('./databaseerror.js'),
|
2017-04-18 11:57:59 +02:00
|
|
|
safe = require('safetydance'),
|
2016-03-07 09:30:43 -08:00
|
|
|
util = require('util');
|
|
|
|
|
|
2017-04-18 11:57:59 +02:00
|
|
|
var BACKUPS_FIELDS = [ 'id', 'creationTime', 'version', 'type', 'dependsOn', 'state', 'restoreConfigJson' ];
|
2016-03-07 09:30:43 -08:00
|
|
|
|
|
|
|
|
exports = module.exports = {
|
|
|
|
|
add: add,
|
|
|
|
|
getPaged: getPaged,
|
|
|
|
|
get: get,
|
|
|
|
|
del: del,
|
2016-03-07 17:52:13 -08:00
|
|
|
getByAppIdPaged: getByAppIdPaged,
|
2016-03-07 09:30:43 -08:00
|
|
|
|
|
|
|
|
_clear: clear,
|
|
|
|
|
|
|
|
|
|
BACKUP_TYPE_APP: 'app',
|
|
|
|
|
BACKUP_TYPE_BOX: 'box',
|
|
|
|
|
|
|
|
|
|
BACKUP_STATE_NORMAL: 'normal', // should rename to created to avoid listing in UI?
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
function postProcess(result) {
|
|
|
|
|
assert.strictEqual(typeof result, 'object');
|
|
|
|
|
|
|
|
|
|
result.dependsOn = result.dependsOn ? result.dependsOn.split(',') : [ ];
|
2017-04-18 11:57:59 +02:00
|
|
|
|
|
|
|
|
result.restoreConfig = result.restoreConfigJson ? safe.JSON.parse(result.restoreConfigJson) : null;
|
|
|
|
|
delete result.restoreConfigJson;
|
2016-03-07 09:30:43 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getPaged(page, perPage, callback) {
|
|
|
|
|
assert(typeof page === 'number' && page > 0);
|
|
|
|
|
assert(typeof perPage === 'number' && perPage > 0);
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
database.query('SELECT ' + BACKUPS_FIELDS + ' FROM backups WHERE type = ? AND state = ? ORDER BY creationTime DESC LIMIT ?,?',
|
|
|
|
|
[ exports.BACKUP_TYPE_BOX, exports.BACKUP_STATE_NORMAL, (page-1)*perPage, perPage ], function (error, results) {
|
|
|
|
|
if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error));
|
|
|
|
|
|
|
|
|
|
results.forEach(function (result) { postProcess(result); });
|
|
|
|
|
|
|
|
|
|
callback(null, results);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getByAppIdPaged(page, perPage, appId, callback) {
|
|
|
|
|
assert(typeof page === 'number' && page > 0);
|
|
|
|
|
assert(typeof perPage === 'number' && perPage > 0);
|
|
|
|
|
assert.strictEqual(typeof appId, 'string');
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2017-01-04 21:41:31 -08:00
|
|
|
// box versions (0.93.x and below) used to use appbackup_ prefix
|
2016-04-04 12:20:34 -07:00
|
|
|
database.query('SELECT ' + BACKUPS_FIELDS + ' FROM backups WHERE type = ? AND state = ? AND id LIKE ? ORDER BY creationTime DESC LIMIT ?,?',
|
2017-01-05 00:52:43 -08:00
|
|
|
[ exports.BACKUP_TYPE_APP, exports.BACKUP_STATE_NORMAL, '%app%\\_' + appId + '\\_%', (page-1)*perPage, perPage ], function (error, results) {
|
2016-03-07 09:30:43 -08:00
|
|
|
if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error));
|
|
|
|
|
|
|
|
|
|
results.forEach(function (result) { postProcess(result); });
|
|
|
|
|
|
|
|
|
|
callback(null, results);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-04 12:20:34 -07:00
|
|
|
function get(id, callback) {
|
|
|
|
|
assert.strictEqual(typeof id, 'string');
|
2016-03-07 09:30:43 -08:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2016-04-04 12:20:34 -07:00
|
|
|
database.query('SELECT ' + BACKUPS_FIELDS + ' FROM backups WHERE id = ? ORDER BY creationTime DESC',
|
|
|
|
|
[ id ], function (error, result) {
|
2016-03-07 09:30:43 -08:00
|
|
|
if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error));
|
|
|
|
|
if (result.length === 0) return callback(new DatabaseError(DatabaseError.NOT_FOUND));
|
|
|
|
|
|
|
|
|
|
postProcess(result[0]);
|
|
|
|
|
|
|
|
|
|
callback(null, result[0]);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function add(backup, callback) {
|
|
|
|
|
assert(backup && typeof backup === 'object');
|
2016-04-04 12:20:34 -07:00
|
|
|
assert.strictEqual(typeof backup.id, 'string');
|
2016-03-07 09:30:43 -08:00
|
|
|
assert.strictEqual(typeof backup.version, 'string');
|
|
|
|
|
assert(backup.type === exports.BACKUP_TYPE_APP || backup.type === exports.BACKUP_TYPE_BOX);
|
|
|
|
|
assert(util.isArray(backup.dependsOn));
|
2017-04-18 11:57:59 +02:00
|
|
|
assert.strictEqual(typeof backup.restoreConfig, 'object');
|
2016-03-07 09:30:43 -08:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
var creationTime = backup.creationTime || new Date(); // allow tests to set the time
|
2017-04-18 11:57:59 +02:00
|
|
|
var restoreConfig = backup.restoreConfig ? JSON.stringify(backup.restoreConfig) : '';
|
2016-03-07 09:30:43 -08:00
|
|
|
|
2017-04-18 11:57:59 +02:00
|
|
|
database.query('INSERT INTO backups (id, version, type, creationTime, state, dependsOn, restoreConfigJson) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
|
|
|
|
[ backup.id, backup.version, backup.type, creationTime, exports.BACKUP_STATE_NORMAL, backup.dependsOn.join(','), restoreConfig ],
|
2016-03-07 09:30:43 -08:00
|
|
|
function (error) {
|
|
|
|
|
if (error && error.code === 'ER_DUP_ENTRY') return callback(new DatabaseError(DatabaseError.ALREADY_EXISTS));
|
|
|
|
|
if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error));
|
|
|
|
|
|
|
|
|
|
callback(null);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clear(callback) {
|
|
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
|
|
|
|
database.query('TRUNCATE TABLE backups', [], function (error) {
|
|
|
|
|
if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error));
|
|
|
|
|
callback(null);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-04 12:20:34 -07:00
|
|
|
function del(id, callback) {
|
|
|
|
|
assert.strictEqual(typeof id, 'string');
|
2016-03-07 09:30:43 -08:00
|
|
|
assert.strictEqual(typeof callback, 'function');
|
|
|
|
|
|
2017-04-23 11:34:46 -07:00
|
|
|
get(id, function (error, result) {
|
|
|
|
|
if (error && error.reason === DatabaseError.NOT_FOUND) return callback();
|
|
|
|
|
if (error) return callback(error);
|
|
|
|
|
|
|
|
|
|
var whereClause = [ 'id=?' ], whereArgs = [ result.id ];
|
|
|
|
|
result.dependsOn.forEach(function (id) {
|
|
|
|
|
whereClause.push('id=?');
|
|
|
|
|
whereArgs.push(id);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
database.query('DELETE FROM backups WHERE ' + whereClause.join(' OR '), whereArgs, function (error) {
|
|
|
|
|
if (error) return callback(new DatabaseError(DatabaseError.INTERNAL_ERROR, error));
|
|
|
|
|
callback(null);
|
|
|
|
|
});
|
2016-03-07 09:30:43 -08:00
|
|
|
});
|
|
|
|
|
}
|