2013-10-03 17:27:29 +04:00
|
|
|
/*
|
|
|
|
* Copyright (C) by Klaas Freitag <freitag@owncloud.com>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; version 2 of the License.
|
|
|
|
*
|
|
|
|
* This program 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 General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SYNCJOURNALDB_H
|
|
|
|
#define SYNCJOURNALDB_H
|
|
|
|
|
|
|
|
#include <QObject>
|
2013-10-04 23:02:23 +04:00
|
|
|
#include <qmutex.h>
|
2013-10-16 13:59:54 +04:00
|
|
|
#include <QDateTime>
|
2013-11-11 14:11:45 +04:00
|
|
|
#include <QHash>
|
2013-10-03 17:27:29 +04:00
|
|
|
|
2014-04-25 01:45:20 +04:00
|
|
|
#include "utility.h"
|
2014-10-14 13:14:57 +04:00
|
|
|
#include "ownsql.h"
|
2014-04-25 01:45:20 +04:00
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
namespace OCC {
|
2013-10-03 17:27:29 +04:00
|
|
|
class SyncJournalFileRecord;
|
2015-01-16 12:17:19 +03:00
|
|
|
class SyncJournalErrorBlacklistRecord;
|
2013-10-03 17:27:29 +04:00
|
|
|
|
2015-06-29 19:56:09 +03:00
|
|
|
/**
|
2015-10-05 06:20:09 +03:00
|
|
|
* @brief Class that handles the sync database
|
2014-04-01 15:41:47 +04:00
|
|
|
*
|
2015-10-05 06:20:09 +03:00
|
|
|
* This class is thread safe. All public functions lock the mutex.
|
2015-06-29 19:56:09 +03:00
|
|
|
* @ingroup libsync
|
2014-04-01 15:41:47 +04:00
|
|
|
*/
|
2014-04-25 01:45:20 +04:00
|
|
|
class OWNCLOUDSYNC_EXPORT SyncJournalDb : public QObject
|
2013-10-03 17:27:29 +04:00
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit SyncJournalDb(const QString& path, QObject *parent = 0);
|
2013-11-18 12:59:59 +04:00
|
|
|
virtual ~SyncJournalDb();
|
2016-04-11 13:40:19 +03:00
|
|
|
|
|
|
|
// to verify that the record could be queried successfully check
|
|
|
|
// with SyncJournalFileRecord::isValid()
|
|
|
|
SyncJournalFileRecord getFileRecord(const QString& filename);
|
2013-10-03 19:48:04 +04:00
|
|
|
bool setFileRecord( const SyncJournalFileRecord& record );
|
2015-11-10 17:05:00 +03:00
|
|
|
|
|
|
|
/// Like setFileRecord, but preserves checksums
|
|
|
|
bool setFileRecordMetadata( const SyncJournalFileRecord& record );
|
|
|
|
|
2013-10-28 13:47:10 +04:00
|
|
|
bool deleteFileRecord( const QString& filename, bool recursively = false );
|
2013-10-04 16:44:57 +04:00
|
|
|
int getFileRecordCount();
|
2015-10-28 16:42:44 +03:00
|
|
|
bool updateFileRecordChecksum(const QString& filename,
|
2015-11-23 13:53:06 +03:00
|
|
|
const QByteArray& contentChecksum,
|
|
|
|
const QByteArray& contentChecksumType);
|
2013-10-04 16:44:57 +04:00
|
|
|
bool exists();
|
2014-10-21 17:41:11 +04:00
|
|
|
void walCheckpoint();
|
2013-12-03 17:47:32 +04:00
|
|
|
|
2014-10-13 16:49:53 +04:00
|
|
|
QString databaseFilePath();
|
2014-10-13 16:14:43 +04:00
|
|
|
static qint64 getPHash(const QString& );
|
|
|
|
|
2015-01-16 12:17:19 +03:00
|
|
|
void updateErrorBlacklistEntry( const SyncJournalErrorBlacklistRecord& item );
|
|
|
|
void wipeErrorBlacklistEntry(const QString& file);
|
|
|
|
int wipeErrorBlacklist();
|
|
|
|
int errorBlackListEntryCount();
|
2013-10-03 20:52:02 +04:00
|
|
|
|
2013-10-16 13:59:54 +04:00
|
|
|
struct DownloadInfo {
|
|
|
|
DownloadInfo() : _errorCount(0), _valid(false) {}
|
|
|
|
QString _tmpfile;
|
|
|
|
QByteArray _etag;
|
|
|
|
int _errorCount;
|
|
|
|
bool _valid;
|
|
|
|
};
|
|
|
|
struct UploadInfo {
|
2014-06-20 14:37:49 +04:00
|
|
|
UploadInfo() : _chunk(0), _transferid(0), _size(0), _errorCount(0), _valid(false) {}
|
2013-10-16 13:59:54 +04:00
|
|
|
int _chunk;
|
|
|
|
int _transferid;
|
|
|
|
quint64 _size; //currently unused
|
|
|
|
QDateTime _modtime;
|
|
|
|
int _errorCount;
|
|
|
|
bool _valid;
|
|
|
|
};
|
|
|
|
|
2014-07-28 14:12:52 +04:00
|
|
|
struct PollInfo {
|
|
|
|
QString _file;
|
|
|
|
QString _url;
|
|
|
|
time_t _modtime;
|
|
|
|
};
|
|
|
|
|
2013-10-16 13:59:54 +04:00
|
|
|
DownloadInfo getDownloadInfo(const QString &file);
|
|
|
|
void setDownloadInfo(const QString &file, const DownloadInfo &i);
|
2014-09-03 14:11:03 +04:00
|
|
|
QVector<DownloadInfo> getAndDeleteStaleDownloadInfos(const QSet<QString>& keep);
|
2014-11-05 16:52:57 +03:00
|
|
|
int downloadInfoCount();
|
2014-09-03 14:11:03 +04:00
|
|
|
|
2013-10-16 13:59:54 +04:00
|
|
|
UploadInfo getUploadInfo(const QString &file);
|
|
|
|
void setUploadInfo(const QString &file, const UploadInfo &i);
|
2014-09-03 14:11:03 +04:00
|
|
|
bool deleteStaleUploadInfos(const QSet<QString>& keep);
|
|
|
|
|
2015-01-16 12:17:19 +03:00
|
|
|
SyncJournalErrorBlacklistRecord errorBlacklistEntry( const QString& );
|
|
|
|
bool deleteStaleErrorBlacklistEntries(const QSet<QString>& keep);
|
2014-09-03 14:11:03 +04:00
|
|
|
|
2014-02-12 16:44:55 +04:00
|
|
|
void avoidRenamesOnNextSync(const QString &path);
|
2014-07-28 14:12:52 +04:00
|
|
|
void setPollInfo(const PollInfo &);
|
|
|
|
QVector<PollInfo> getPollInfos();
|
2013-11-20 16:44:01 +04:00
|
|
|
|
2015-05-20 17:28:06 +03:00
|
|
|
enum SelectiveSyncListType {
|
2015-05-26 15:41:29 +03:00
|
|
|
/** The black list is the list of folders that are unselected in the selective sync dialog.
|
|
|
|
* For the sync engine, those folders are considered as if they were not there, so the local
|
|
|
|
* folders will be deleted */
|
2015-05-20 17:28:06 +03:00
|
|
|
SelectiveSyncBlackList = 1,
|
2015-10-05 06:20:09 +03:00
|
|
|
/** When a shared folder has a size bigger than a configured size, it is by default not sync'ed
|
2015-05-26 15:41:29 +03:00
|
|
|
* Unless it is in the white list, in which case the folder is sync'ed and all its children.
|
|
|
|
* If a folder is both on the black and the white list, the black list wins */
|
2015-05-20 17:28:06 +03:00
|
|
|
SelectiveSyncWhiteList = 2,
|
2015-10-05 06:20:09 +03:00
|
|
|
/** List of big sync folders that have not been confirmed by the user yet and that the UI
|
2015-05-26 15:41:29 +03:00
|
|
|
* should notify about */
|
2015-05-20 17:28:06 +03:00
|
|
|
SelectiveSyncUndecidedList = 3
|
|
|
|
};
|
|
|
|
/* return the specified list from the database */
|
2016-04-06 16:01:28 +03:00
|
|
|
QStringList getSelectiveSyncList(SelectiveSyncListType type, bool *ok);
|
2015-05-20 17:28:06 +03:00
|
|
|
/* Write the selective sync list (remove all other entries of that list */
|
|
|
|
void setSelectiveSyncList(SelectiveSyncListType type, const QStringList &list);
|
|
|
|
|
2014-06-03 19:22:40 +04:00
|
|
|
/**
|
2015-10-05 06:20:09 +03:00
|
|
|
* Make sure that on the next sync, fileName is not read from the DB but uses the PROPFIND to
|
2014-06-03 19:22:40 +04:00
|
|
|
* get the info from the server
|
|
|
|
*/
|
|
|
|
void avoidReadFromDbOnNextSync(const QString& fileName);
|
|
|
|
|
2015-06-19 14:51:55 +03:00
|
|
|
/**
|
|
|
|
* Ensures full remote discovery happens on the next sync.
|
|
|
|
*
|
|
|
|
* Equivalent to calling avoidReadFromDbOnNextSync() for all files.
|
|
|
|
*/
|
|
|
|
void forceRemoteDiscoveryNextSync();
|
|
|
|
|
2015-04-08 11:50:08 +03:00
|
|
|
bool postSyncCleanup(const QSet<QString>& filepathsToKeep,
|
|
|
|
const QSet<QString>& prefixesToKeep);
|
2013-10-16 13:59:54 +04:00
|
|
|
|
2015-10-05 06:20:09 +03:00
|
|
|
/* Because sqlite transactions are really slow, we encapsulate everything in big transactions
|
2013-11-18 12:59:59 +04:00
|
|
|
* Commit will actually commit the transaction and create a new one.
|
|
|
|
*/
|
2013-11-21 14:13:58 +04:00
|
|
|
void commit(const QString &context, bool startTrans = true);
|
2014-10-20 19:20:58 +04:00
|
|
|
void commitIfNeededAndStartNewTransaction(const QString &context);
|
2013-11-18 12:59:59 +04:00
|
|
|
|
2013-11-18 12:58:02 +04:00
|
|
|
void close();
|
2013-11-21 14:13:58 +04:00
|
|
|
|
2014-04-01 15:41:47 +04:00
|
|
|
/**
|
|
|
|
* return true if everything is correct
|
|
|
|
*/
|
|
|
|
bool isConnected();
|
|
|
|
|
2015-11-23 13:53:06 +03:00
|
|
|
/**
|
|
|
|
* Returns the checksum type for an id.
|
|
|
|
*/
|
|
|
|
QByteArray getChecksumType(int checksumTypeId);
|
|
|
|
|
2013-10-03 17:27:29 +04:00
|
|
|
private:
|
2013-10-25 15:30:45 +04:00
|
|
|
bool updateDatabaseStructure();
|
2014-10-09 16:49:51 +04:00
|
|
|
bool updateMetadataTableStructure();
|
2015-01-16 12:17:19 +03:00
|
|
|
bool updateErrorBlacklistTableStructure();
|
2014-10-14 13:14:57 +04:00
|
|
|
bool sqlFail(const QString& log, const SqlQuery &query );
|
2013-11-25 18:11:37 +04:00
|
|
|
void commitInternal(const QString &context, bool startTrans = true);
|
|
|
|
void startTransaction();
|
|
|
|
void commitTransaction();
|
|
|
|
QStringList tableColumns( const QString& table );
|
2014-04-01 15:41:47 +04:00
|
|
|
bool checkConnect();
|
2013-10-25 15:30:45 +04:00
|
|
|
|
2015-06-19 14:51:55 +03:00
|
|
|
// Same as forceRemoteDiscoveryNextSync but without acquiring the lock
|
|
|
|
void forceRemoteDiscoveryNextSyncLocked();
|
|
|
|
|
2015-10-28 13:00:03 +03:00
|
|
|
// Returns the integer id of the checksum type
|
|
|
|
//
|
|
|
|
// Returns 0 on failure and for empty checksum types.
|
|
|
|
int mapChecksumType(const QByteArray& checksumType);
|
|
|
|
|
2014-10-14 13:14:57 +04:00
|
|
|
SqlDatabase _db;
|
2014-10-13 16:49:53 +04:00
|
|
|
QString _dbFile;
|
2013-10-04 23:02:23 +04:00
|
|
|
QMutex _mutex; // Public functions are protected with the mutex.
|
2013-11-21 14:13:58 +04:00
|
|
|
int _transaction;
|
2015-10-30 16:03:08 +03:00
|
|
|
|
|
|
|
// NOTE! when adding a query, don't forget to reset it in SyncJournalDb::close
|
2014-10-14 13:14:57 +04:00
|
|
|
QScopedPointer<SqlQuery> _getFileRecordQuery;
|
|
|
|
QScopedPointer<SqlQuery> _setFileRecordQuery;
|
2015-10-28 13:00:03 +03:00
|
|
|
QScopedPointer<SqlQuery> _setFileRecordChecksumQuery;
|
2014-10-14 13:14:57 +04:00
|
|
|
QScopedPointer<SqlQuery> _getDownloadInfoQuery;
|
|
|
|
QScopedPointer<SqlQuery> _setDownloadInfoQuery;
|
|
|
|
QScopedPointer<SqlQuery> _deleteDownloadInfoQuery;
|
|
|
|
QScopedPointer<SqlQuery> _getUploadInfoQuery;
|
|
|
|
QScopedPointer<SqlQuery> _setUploadInfoQuery;
|
|
|
|
QScopedPointer<SqlQuery> _deleteUploadInfoQuery;
|
|
|
|
QScopedPointer<SqlQuery> _deleteFileRecordPhash;
|
|
|
|
QScopedPointer<SqlQuery> _deleteFileRecordRecursively;
|
2015-01-16 12:17:19 +03:00
|
|
|
QScopedPointer<SqlQuery> _getErrorBlacklistQuery;
|
|
|
|
QScopedPointer<SqlQuery> _setErrorBlacklistQuery;
|
2015-05-20 17:28:06 +03:00
|
|
|
QScopedPointer<SqlQuery> _getSelectiveSyncListQuery;
|
2015-10-28 13:00:03 +03:00
|
|
|
QScopedPointer<SqlQuery> _getChecksumTypeIdQuery;
|
2015-11-23 13:53:06 +03:00
|
|
|
QScopedPointer<SqlQuery> _getChecksumTypeQuery;
|
2015-10-28 13:00:03 +03:00
|
|
|
QScopedPointer<SqlQuery> _insertChecksumTypeQuery;
|
2014-08-07 14:10:32 +04:00
|
|
|
|
|
|
|
/* This is the list of paths we called avoidReadFromDbOnNextSync on.
|
|
|
|
* It means that they should not be written to the DB in any case since doing
|
|
|
|
* that would write the etag and would void the purpose of avoidReadFromDbOnNextSync
|
|
|
|
*/
|
|
|
|
QList<QString> _avoidReadFromDbOnNextSyncFilter;
|
2013-10-03 17:27:29 +04:00
|
|
|
};
|
|
|
|
|
2014-11-19 16:14:54 +03:00
|
|
|
bool OWNCLOUDSYNC_EXPORT
|
|
|
|
operator==(const SyncJournalDb::DownloadInfo & lhs,
|
|
|
|
const SyncJournalDb::DownloadInfo & rhs);
|
|
|
|
bool OWNCLOUDSYNC_EXPORT
|
|
|
|
operator==(const SyncJournalDb::UploadInfo & lhs,
|
|
|
|
const SyncJournalDb::UploadInfo & rhs);
|
2014-10-23 17:15:47 +04:00
|
|
|
|
2014-11-10 00:34:07 +03:00
|
|
|
} // namespace OCC
|
2013-10-03 17:27:29 +04:00
|
|
|
#endif // SYNCJOURNALDB_H
|