'use strict'; var assert = require('assert'), BoxError = require('./boxerror.js'), database = require('./database.js'), safe = require('safetydance'), util = require('util'); var BACKUPS_FIELDS = [ 'id', 'identifier', 'creationTime', 'packageVersion', 'type', 'dependsOn', 'state', 'manifestJson', 'format', 'preserveSecs', 'encryptionVersion' ]; exports = module.exports = { add, getByTypePaged, getByIdentifierPaged, getByIdentifierAndStatePaged, get, del, update, list, _clear: clear }; function postProcess(result) { assert.strictEqual(typeof result, 'object'); result.dependsOn = result.dependsOn ? result.dependsOn.split(',') : [ ]; result.manifest = result.manifestJson ? safe.JSON.parse(result.manifestJson) : null; delete result.manifestJson; } function getByIdentifierAndStatePaged(identifier, state, page, perPage, callback) { assert.strictEqual(typeof identifier, 'string'); assert.strictEqual(typeof state, 'string'); 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 identifier = ? AND state = ? ORDER BY creationTime DESC LIMIT ?,?', [ identifier, state, (page-1)*perPage, perPage ], function (error, results) { if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results.forEach(function (result) { postProcess(result); }); callback(null, results); }); } function getByTypePaged(type, page, perPage, callback) { assert.strictEqual(typeof type, 'string'); 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 = ? ORDER BY creationTime DESC LIMIT ?,?', [ type, (page-1)*perPage, perPage ], function (error, results) { if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results.forEach(function (result) { postProcess(result); }); callback(null, results); }); } function getByIdentifierPaged(identifier, page, perPage, callback) { assert.strictEqual(typeof identifier, 'string'); 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 identifier = ? ORDER BY creationTime DESC LIMIT ?,?', [ identifier, (page-1)*perPage, perPage ], function (error, results) { if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results.forEach(function (result) { postProcess(result); }); callback(null, results); }); } function list(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 ORDER BY creationTime DESC LIMIT ?,?', [ (page-1)*perPage, perPage ], function (error, results) { if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); results.forEach(function (result) { postProcess(result); }); callback(null, results); }); } function get(id, callback) { assert.strictEqual(typeof id, 'string'); assert.strictEqual(typeof callback, 'function'); database.query('SELECT ' + BACKUPS_FIELDS + ' FROM backups WHERE id = ? ORDER BY creationTime DESC', [ id ], function (error, result) { if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); if (result.length === 0) return callback(new BoxError(BoxError.NOT_FOUND, 'Backup not found')); postProcess(result[0]); callback(null, result[0]); }); } function add(id, data, callback) { assert(data && typeof data === 'object'); assert.strictEqual(typeof id, 'string'); assert(data.encryptionVersion === null || typeof data.encryptionVersion === 'number'); assert.strictEqual(typeof data.packageVersion, 'string'); assert.strictEqual(typeof data.type, 'string'); assert.strictEqual(typeof data.identifier, 'string'); assert.strictEqual(typeof data.state, 'string'); assert(util.isArray(data.dependsOn)); assert.strictEqual(typeof data.manifest, 'object'); assert.strictEqual(typeof data.format, 'string'); assert.strictEqual(typeof callback, 'function'); var creationTime = data.creationTime || new Date(); // allow tests to set the time var manifestJson = JSON.stringify(data.manifest); database.query('INSERT INTO backups (id, identifier, encryptionVersion, packageVersion, type, creationTime, state, dependsOn, manifestJson, format) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [ id, data.identifier, data.encryptionVersion, data.packageVersion, data.type, creationTime, data.state, data.dependsOn.join(','), manifestJson, data.format ], function (error) { if (error && error.code === 'ER_DUP_ENTRY') return callback(new BoxError(BoxError.ALREADY_EXISTS)); if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); } function update(id, backup, callback) { assert.strictEqual(typeof id, 'string'); assert.strictEqual(typeof backup, 'object'); assert.strictEqual(typeof callback, 'function'); var fields = [ ], values = [ ]; for (var p in backup) { fields.push(p + ' = ?'); values.push(backup[p]); } values.push(id); database.query('UPDATE backups SET ' + fields.join(', ') + ' WHERE id = ?', values, function (error) { if (error && error.reason === BoxError.NOT_FOUND) return callback(new BoxError(BoxError.NOT_FOUND, 'Backup not found')); if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); } function clear(callback) { assert.strictEqual(typeof callback, 'function'); database.query('TRUNCATE TABLE backups', [], function (error) { if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); } function del(id, callback) { assert.strictEqual(typeof id, 'string'); assert.strictEqual(typeof callback, 'function'); database.query('DELETE FROM backups WHERE id=?', [ id ], function (error) { if (error) return callback(new BoxError(BoxError.DATABASE_ERROR, error)); callback(null); }); }