File indexing completed on 2024-11-10 04:40:18

0001 /*
0002     SPDX-FileCopyrightText: 2014 Christian Mollekopf <mollekopf@kolabsys.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 #include "dbinitializer.h"
0007 #include "akonadiserver_debug.h"
0008 
0009 #include "storage/datastore.h"
0010 #include "storage/parttypehelper.h"
0011 #include <storage/querybuilder.h>
0012 
0013 #include "shared/akranges.h"
0014 
0015 using namespace Akonadi;
0016 using namespace Akonadi::Server;
0017 using namespace AkRanges;
0018 
0019 DbInitializer::~DbInitializer()
0020 {
0021     cleanup();
0022 }
0023 
0024 Resource DbInitializer::createResource(const char *name)
0025 {
0026     Resource res;
0027     qint64 id = -1;
0028     res.setName(QLatin1StringView(name));
0029     const bool ret = res.insert(&id);
0030     Q_ASSERT(ret);
0031     Q_UNUSED(ret)
0032     mResource = res;
0033     return res;
0034 }
0035 
0036 Collection DbInitializer::createCollection(const char *name, const Collection &parent)
0037 {
0038     Collection col;
0039     if (parent.isValid()) {
0040         col.setParent(parent);
0041     }
0042     col.setName(QLatin1StringView(name));
0043     col.setRemoteId(QLatin1StringView(name));
0044     col.setResource(mResource);
0045     const bool ret = col.insert();
0046     Q_ASSERT(ret);
0047     Q_UNUSED(ret)
0048     return col;
0049 }
0050 
0051 PimItem DbInitializer::createItem(const char *name, const Collection &parent)
0052 {
0053     PimItem item;
0054     MimeType mimeType = MimeType::retrieveByName(QStringLiteral("test"));
0055     if (!mimeType.isValid()) {
0056         MimeType mt;
0057         mt.setName(QStringLiteral("test"));
0058         mt.insert();
0059         mimeType = mt;
0060     }
0061     item.setMimeType(mimeType);
0062     item.setCollection(parent);
0063     item.setRemoteId(QLatin1StringView(name));
0064     const bool ret = item.insert();
0065     Q_ASSERT(ret);
0066     Q_UNUSED(ret)
0067     return item;
0068 }
0069 
0070 Part DbInitializer::createPart(qint64 pimItem, const QByteArray &partName, const QByteArray &partData)
0071 {
0072     auto partType = PartTypeHelper::parseFqName(QString::fromLatin1(partName));
0073     PartType type = PartType::retrieveByFQNameOrCreate(partType.first, partType.second);
0074 
0075     Part part;
0076     part.setPimItemId(pimItem);
0077     part.setPartTypeId(type.id());
0078     part.setData(partData);
0079     part.setDatasize(partData.size());
0080     const bool ret = part.insert();
0081     Q_ASSERT(ret);
0082     Q_UNUSED(ret)
0083     return part;
0084 }
0085 
0086 QByteArray DbInitializer::toByteArray(bool enabled)
0087 {
0088     if (enabled) {
0089         return "TRUE";
0090     }
0091     return "FALSE";
0092 }
0093 
0094 QByteArray DbInitializer::toByteArray(Collection::Tristate tristate)
0095 {
0096     switch (tristate) {
0097     case Collection::True:
0098         return "TRUE";
0099     case Collection::False:
0100         return "FALSE";
0101     case Collection::Undefined:
0102     default:
0103         break;
0104     }
0105     return "DEFAULT";
0106 }
0107 
0108 Akonadi::Protocol::FetchCollectionsResponsePtr
0109 DbInitializer::listResponse(const Collection &col, bool ancestors, bool mimetypes, const QStringList &ancestorFetchScope)
0110 {
0111     auto resp = Akonadi::Protocol::FetchCollectionsResponsePtr::create(col.id());
0112     resp->setParentId(col.parentId());
0113     resp->setName(col.name());
0114     if (mimetypes) {
0115         resp->setMimeTypes(col.mimeTypes() | Views::transform(&MimeType::name) | Actions::toQList);
0116     }
0117     resp->setRemoteId(col.remoteId());
0118     resp->setRemoteRevision(col.remoteRevision());
0119     resp->setResource(col.resource().name());
0120     resp->setIsVirtual(col.isVirtual());
0121     Akonadi::Protocol::CachePolicy cp;
0122     cp.setInherit(true);
0123     cp.setLocalParts({QLatin1StringView("ALL")});
0124     resp->setCachePolicy(cp);
0125     if (ancestors) {
0126         QList<Akonadi::Protocol::Ancestor> ancs;
0127         Collection parent = col.parent();
0128         while (parent.isValid()) {
0129             Akonadi::Protocol::Ancestor anc;
0130             anc.setId(parent.id());
0131             anc.setRemoteId(parent.remoteId());
0132             anc.setName(parent.name());
0133             if (!ancestorFetchScope.isEmpty()) {
0134                 anc.setRemoteId(parent.remoteId());
0135                 Akonadi::Protocol::Attributes attrs;
0136                 const auto parentAttrs = parent.attributes();
0137                 for (const CollectionAttribute &attr : parentAttrs) {
0138                     if (ancestorFetchScope.contains(QString::fromLatin1(attr.type()))) {
0139                         attrs.insert(attr.type(), attr.value());
0140                     }
0141                 }
0142                 attrs.insert("ENABLED", parent.enabled() ? "TRUE" : "FALSE");
0143                 anc.setAttributes(attrs);
0144             }
0145             parent = parent.parent();
0146             ancs.push_back(anc);
0147         }
0148         // Root
0149         ancs.push_back(Akonadi::Protocol::Ancestor(0));
0150         resp->setAncestors(ancs);
0151     }
0152     resp->setEnabled(col.enabled());
0153     resp->setDisplayPref(static_cast<Tristate>(col.displayPref()));
0154     resp->setSyncPref(static_cast<Tristate>(col.syncPref()));
0155     resp->setIndexPref(static_cast<Tristate>(col.indexPref()));
0156 
0157     Akonadi::Protocol::Attributes attrs;
0158     const auto colAttrs = col.attributes();
0159     for (const CollectionAttribute &attr : colAttrs) {
0160         attrs.insert(attr.type(), attr.value());
0161     }
0162     resp->setAttributes(attrs);
0163     return resp;
0164 }
0165 
0166 Akonadi::Protocol::FetchItemsResponsePtr DbInitializer::fetchResponse(const PimItem &item)
0167 {
0168     auto resp = Akonadi::Protocol::FetchItemsResponsePtr::create();
0169     resp->setId(item.id());
0170     resp->setRevision(item.rev());
0171     resp->setMimeType(item.mimeType().name());
0172     resp->setRemoteId(item.remoteId());
0173     resp->setParentId(item.collectionId());
0174     resp->setSize(item.size());
0175     resp->setMTime(item.datetime());
0176     resp->setRemoteRevision(item.remoteRevision());
0177     resp->setGid(item.gid());
0178     const auto flags = item.flags();
0179     QList<QByteArray> flagNames;
0180     for (const auto &flag : flags) {
0181         flagNames.push_back(flag.name().toUtf8());
0182     }
0183     resp->setFlags(flagNames);
0184 
0185     return resp;
0186 }
0187 
0188 Collection DbInitializer::collection(const char *name)
0189 {
0190     return Collection::retrieveByName(QLatin1StringView(name));
0191 }
0192 
0193 void DbInitializer::cleanup()
0194 {
0195     const Collection::List collections = mResource.collections();
0196     for (Collection col : collections) {
0197         if (!col.isVirtual()) {
0198             col.remove();
0199         }
0200     }
0201     mResource.remove();
0202 
0203     if (DataStore::self()->database().isOpen()) {
0204         {
0205             QueryBuilder qb(Relation::tableName(), QueryBuilder::Delete);
0206             qb.exec();
0207         }
0208         {
0209             QueryBuilder qb(Tag::tableName(), QueryBuilder::Delete);
0210             qb.exec();
0211         }
0212         {
0213             QueryBuilder qb(TagType::tableName(), QueryBuilder::Delete);
0214             qb.exec();
0215         }
0216     }
0217 
0218     const Part::List allParts = Part::retrieveAll();
0219     for (Part part : allParts) {
0220         part.remove();
0221     }
0222     const PimItem::List allItems = PimItem::retrieveAll();
0223     for (PimItem item : allItems) {
0224         item.remove();
0225     }
0226 }