// Copyright (C) 2015, The Duplicati Team // http://www.duplicati.com, info@duplicati.com // // This library is free software; you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as // published by the Free Software Foundation; either version 2.1 of the // License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA using System; using System.Linq; using System.Threading.Tasks; using CoCoL; using Duplicati.Library.Main.Database; using System.Collections.Generic; namespace Duplicati.Library.Main.Operation.Common { /// /// Asynchronous interface that ensures all requests /// to the database are performed in a sequential manner /// internal class DatabaseCommon : SingleRunner, IBackendHandlerDatabase, IIndexVolumeCreatorDatabase, IDisposable { protected LocalDatabase m_db; protected Options m_options; public DatabaseCommon(LocalDatabase db, Options options) : base() { m_db = db; m_options = options; } /// /// Creates and registers a remote volume /// /// The newly created volume ID. /// The name of the remote file. /// The type of the remote file. /// The state of the remote file. public Task RegisterRemoteVolumeAsync(string name, RemoteVolumeType type, RemoteVolumeState state) { return RunOnMain(() => m_db.RegisterRemoteVolume(name, type, state)); } /// /// Updates the remote volume information. /// /// An awaitable task. /// The name of the remote volume to update. /// The new volume state. /// The new volume size. /// The new volume hash. /// If set to true suppress cleanup operation. /// The new delete grace time. public Task UpdateRemoteVolumeAsync(string name, RemoteVolumeState state, long size, string hash, bool suppressCleanup = false, TimeSpan deleteGraceTime = default(TimeSpan)) { return RunOnMain(() => m_db.UpdateRemoteVolume(name, state, size, hash, suppressCleanup, deleteGraceTime)); } /// /// Writes the current changes to the database /// /// An awaitable task. /// The message to use for logging the time spent in this operation. /// If set to true, a transaction will be started again after this call. public Task CommitTransactionAsync(string message, bool restart = true) { return RunOnMain(() => { if (m_options.Dryrun) m_db.RollbackTransaction(restart); else m_db.CommitTransaction(message, restart); }); } public Task RollbackTransactionAsync(bool restart = true) { return RunOnMain(() => { m_db.RollbackTransaction(restart); }); } /// /// Renames a remote file in the database /// /// The remote file to rename. /// The old filename. /// The new filename. public Task RenameRemoteFileAsync(string oldname, string newname) { return RunOnMain(() => m_db.RenameRemoteFile(oldname, newname)); } /// /// Writes remote operation log data to the database /// /// An awaitable task. /// The operation performed. /// The remote path used. /// Any data reported by the operation. public Task LogRemoteOperationAsync(string operation, string path, string data) { return RunOnMain(() => m_db.LogRemoteOperation(operation, path, data)); } /// /// Gets a list of all blocks associated with a given volume /// /// The blocks found in the volume. /// The ID of the volume to examine. /// The method called for each item public Task GetBlocksAsync(long volumeid, Action callback) { return RunOnMain(() => { foreach (var n in m_db.GetBlocks(volumeid)) callback(n); }); } /// /// Gets the volume information for a remote file, given the name. /// /// The remote volume information. /// The name of the remote file to query. public Task GetVolumeInfoAsync(string remotename) { return RunOnMain(() => m_db.GetRemoteVolume(remotename)); } /// /// Gets the blocklists contained in a remote volume /// /// The blocklists. /// The ID of the volume to get the blocklists for. /// The blocksize setting. /// The size of the hash in bytes. /// The callback method called for each result public Task GetBlocklistsAsync(long volumeid, int blocksize, int hashsize, Action> callback) { return RunOnMain(() => { foreach (var n in m_db.GetBlocklists(volumeid, blocksize, hashsize)) callback(n); }); } /// /// Gets the ID for a remote volume. /// /// The remote volume ID. /// The remote file name. public Task GetRemoteVolumeIDAsync(string remotename) { return RunOnMain(() => m_db.GetRemoteVolumeID(remotename)); } /// /// Adds a link between a block volume and an index volume /// /// An awaitable task. /// The index volume ID. /// The block volume ID. public Task AddIndexBlockLinkAsync(long indexVolumeID, long blockVolumeID) { return RunOnMain(() => m_db.AddIndexBlockLink(indexVolumeID, blockVolumeID)); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); } } }