1/***************************************************************************
2 * Copyright (C) 2009 by Andras Mantia <amantia@kde.org> *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU Library General Public License as *
6 * published by the Free Software Foundation; either version 2 of the *
7 * License, or (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Library General Public *
15 * License along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
19
20#ifndef PARTHELPER_H
21#define PARTHELPER_H
22
23#include <QtGlobal>
24#include "entities.h"
25#include "../exception.h"
26
27class QString;
28class QVariant;
29class QFile;
30
31namespace Akonadi {
32namespace Server {
33
34class ImapStreamParser;
35
36AKONADI_EXCEPTION_MAKE_INSTANCE(PartHelperException);
37
38/**
39 * Helper methods that store data in a file instead of the database.
40 *
41 * @author Andras Mantia <amantia@kde.org>
42 *
43 * @todo Use exceptions for error handling in all these methods. Requires that all callers
44 * can handle that first though.
45 */
46namespace PartHelper {
47/**
48 * Update payload of an existing part @p part to @p data and size @p dataSize.
49 * Automatically decides whether or not the data should be stored in the databse
50 * or the file system.
51 * @throw PartHelperException if file operations failed
52 */
53void update(Part *part, const QByteArray &data, qint64 dataSize);
54
55/**
56 * Adds a new part to the database and if necessary to the filesystem.
57 * @p part must not be in the database yet (ie. valid() == false) and must have
58 * a data size set.
59 */
60bool insert(Part *part, qint64 *insertId = 0);
61
62/** Deletes @p part from the database and also removes existing filesystem data if needed. */
63bool remove(Part *part);
64/** Deletes all parts which match the given constraint, including all corresponding filesystem data. */
65bool remove(const QString &column, const QVariant &value);
66
67/** Deletes @p fileName, after verifying it's actually one of ours.
68 * @throws PartHelperException if this file is not in our data directory.
69 */
70void removeFile(const QString &fileName);
71
72/**
73 * Reads data from @p streamParser as they arrive from client and writes them
74 * to @p partFile. It will close the file when all data are read.
75 *
76 * @param partFile File to write into. The file must be closed, or opened in write mode
77 * @throws PartHelperException when an error occurs (write fails, data truncated, etc)
78 */
79bool streamToFile(ImapStreamParser *streamParser, QFile &partFile, QIODevice::OpenMode = QIODevice::WriteOnly);
80
81/** Returns the payload data. */
82QByteArray translateData(const QByteArray &data, bool isExternal);
83/** Convenience overload of the above. */
84QByteArray translateData(const Part &part);
85/** Truncate the payload of @p part and update filesystem/database accordingly.
86 * This is more efficient than using update since it does not require the data to be loaded.
87 */
88bool truncate(Part &part);
89
90/** Verifies and if necessary fixes the external reference of this part. */
91bool verify(Part &part);
92
93// private: for unit testing only
94
95/**
96 * Returns a file base name for storing the given item part.
97 * This does not yet include the revision part.
98 */
99QString fileNameForPart(Part *part);
100
101/**
102 * Retruns the base path for storing external payloads.
103 */
104QString storagePath();
105
106/**
107 * Read filename from @p data and returns absolute filepath
108 */
109QString resolveAbsolutePath(const QByteArray &data);
110
111QString updateFileNameRevision(const QString &fileName);
112
113} // namespace PartHelper
114
115} // namespace Server
116} // namespace Akonadi
117
118#endif
119