queryoperation.cpp 12.4 KB
Newer Older
Lukas Appelhans's avatar
Lukas Appelhans committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/* This file is part of the Chakra project

   Copyright (C) 2011 Lukas Appelhans <l.appelhans@gmx.de>

   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; either
   version 2 of the License, or (at your option) any later version.
*/

#include "queryoperation.h"

#include <akabeibackend.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
14
#include <akabeigroup.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
15
#include <akabeidatabase.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
16
#include <akabeiconfig.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
17 18
#include <klocale.h>
#include <QTextStream>
Lukas Appelhans's avatar
Lukas Appelhans committed
19
#include <kio/global.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
20
#include <kdebug.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
21
#include <QDate>
Lukas Appelhans's avatar
Lukas Appelhans committed
22 23
#include <QFile>
#include <QDir>
Lukas Appelhans's avatar
Lukas Appelhans committed
24
#include <QCoreApplication>
Lukas Appelhans's avatar
Lukas Appelhans committed
25 26 27 28 29 30 31 32 33 34 35 36

QueryOperation::QueryOperation(QObject * parent)
  : QObject(parent)
{

}

QueryOperation::~QueryOperation()
{

}

37
void QueryOperation::start(QList<APM::Operation> operations, QMultiHash<APM::Operation, QString> options, QStringList args)
Lukas Appelhans's avatar
Lukas Appelhans committed
38
{
Lukas Appelhans's avatar
Lukas Appelhans committed
39 40 41
    if (operations.contains(APM::ShowInformation)) {
        if (args.isEmpty())
            return;
42
        if (operations.contains(APM::QueryPackageFile)) {
43
            showInformation(QList<Akabei::Package*>() << Akabei::Backend::instance()->loadPackageFromFile(args.first()));
44
        } else {
Lukas Appelhans's avatar
Lukas Appelhans committed
45
            showInformation(Akabei::Backend::instance()->localDatabase()->searchPackages(args.first(), Akabei::SearchNameEqual));
46
            //CHange back to searchPackages when we have sorted results after Name and description
47
        }
Lukas Appelhans's avatar
Lukas Appelhans committed
48 49 50 51 52
    } else if (operations.contains(APM::ShowPackagesOfGroup)) {
        if (args.isEmpty())
            return;
        connect(Akabei::Backend::instance(), SIGNAL(queryGroupsCompleted(QUuid,QList<Akabei::Group*>)), 
                                             SLOT(showGroup(QUuid,QList<Akabei::Group*>)));
53
        Akabei::Backend::instance()->localDatabase()->queryGroups("SELECT * FROM groups WHERE Name LIKE \"" + args.first() + "\"");
Lukas Appelhans's avatar
Lukas Appelhans committed
54 55 56
    } else if (operations.contains(APM::ShowChangelog)) {
        if (args.isEmpty())
            return;
57
        if (operations.contains(APM::QueryPackageFile)) {
58
            showChangelog(QList<Akabei::Package*>() << Akabei::Backend::instance()->loadPackageFromFile(args.first()));
59
        } else {
60
            showChangelog(Akabei::Backend::instance()->localDatabase()->searchPackages(args.first()));
61
        }
62
    } else if (operations.contains(APM::ShowInstalledAsDeps) || operations.contains(APM::ShowInstalledExplicitely)) {
Lukas Appelhans's avatar
Lukas Appelhans committed
63 64 65
        QString query = "SELECT * FROM packages WHERE";
        if (!args.isEmpty())
            query = query + " Name LIKE \"" + args.first() + "\" AND";
66 67 68 69
        if (operations.contains(APM::ShowInstalledAsDeps))
            query = query + " InstallReason LIKE 0";// + QString((int)Akabei::Package::InstalledAsDependencyReason);
        else
            query = query + " InstallReason LIKE 1";
Lukas Appelhans's avatar
Lukas Appelhans committed
70
        showInstalledAsDeps(Akabei::Backend::instance()->localDatabase()->queryPackages(query));
Lukas Appelhans's avatar
Lukas Appelhans committed
71 72 73
    } else if (operations.contains(APM::CheckFiles)) {
        if (args.isEmpty())
            return;
74
        if (operations.contains(APM::QueryPackageFile)) {
75
            checkFiles(QList<Akabei::Package*>() << Akabei::Backend::instance()->loadPackageFromFile(args.first()));
76
        } else {
77
            checkFiles(Akabei::Backend::instance()->localDatabase()->searchPackages(args.first()));
78
        }
Lukas Appelhans's avatar
Lukas Appelhans committed
79 80 81 82 83
    } else if (operations.contains(APM::ShowLocal)) {
        if (args.isEmpty())
            showLocalPackages(QString());
        else
            showLocalPackages(args.first());
84 85
    } else if (operations.contains(APM::ShowOwner) && !args.isEmpty()) {
        showOwner(args.first());
Lukas Appelhans's avatar
Lukas Appelhans committed
86
    } else if (operations.contains(APM::SearchLocal)) {
Lukas Appelhans's avatar
Lukas Appelhans committed
87
        showLocalQuery(Akabei::Backend::instance()->localDatabase()->searchPackages(args.first(), Akabei::SearchNameEqual));
Lukas Appelhans's avatar
Lukas Appelhans committed
88 89
    } else if (operations.contains(APM::ShowNotRequired)) {
        showNotRequired();
Lukas Appelhans's avatar
Lukas Appelhans committed
90 91
    } else if (operations.contains(APM::ShowUpgradeable)) {
        showUpgradeable();
92 93
    } else {
        QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
94 95 96
    }
}

97
void QueryOperation::showInformation(QList<Akabei::Package*> packages)
Lukas Appelhans's avatar
Lukas Appelhans committed
98 99 100 101 102
{
    if (packages.isEmpty())
        return;
    Akabei::Package * pkg = packages.first();
    QTextStream out(stdout);
Lukas Appelhans's avatar
Lukas Appelhans committed
103
    out.setFieldWidth(20);//TODO: Use QFontMetrics to get width of longest word and use that as width of the field (Also in -Si)
Lukas Appelhans's avatar
Lukas Appelhans committed
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
    out.setFieldAlignment(QTextStream::AlignLeft);
    out << i18n("Name") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->name() << endl;
    out << i18n("Version") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << QString(pkg->version().toByteArray().data()) << endl;
    out << i18n("URL") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->url().toString() << endl;
    out << i18n("Licenses") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->license() << endl;
    QStringList groups;
    foreach (Akabei::Group * g, pkg->groups())
        groups << g->name();
    out << i18n("Groups") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << groups.join(" ") << endl;
    out << i18n("Provides") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->provides().join(" ") << endl;
    out << i18n("Depends on") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->dependencies().join(" ") << endl;
    out << i18n("Optional dependencies") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->optionalDependencies().join(" ") << endl;
    //out << i18n("Required by:") << pkg->
    out << i18n("Replaces") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->replaces().join(" ") << endl;
    out << i18n("Installation size") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << KIO::convertSize(pkg->size()) << endl;
    out << i18n("Packager") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->packager() << endl;
    out << i18n("Architecture") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->arch() << endl;
    out << i18n("Creation time") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->buildDate().toString() << endl;
    out << i18n("Installation time") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->installDate().toString() << endl;
    out << i18n("Install reason") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << ((pkg->installReason() == Akabei::Package::InstalledAsDependencyReason) ? i18n("Installed as dependency") : i18n("Installed explicitely")) << endl;
    out << i18n("Installation script") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << (pkg->hasScriptlet() ? i18n("Yes") : i18n("No")) << endl;
    out << i18n("Description") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->description() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
126
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
127
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
128
}
Lukas Appelhans's avatar
Lukas Appelhans committed
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143

void QueryOperation::showGroup(QUuid uuid,QList<Akabei::Group*> groups)
{
    Q_UNUSED(uuid)
    if (groups.isEmpty())
        return;
    Akabei::Group * group = groups.first();
    
    QTextStream out(stdout);
    QMap<QString, Akabei::Package*> sorted;
    foreach (Akabei::Package * pkg, group->packages())
        sorted[pkg->name()] = pkg;
    foreach (Akabei::Package * pkg, sorted.values())
        out << group->name() << ' ' << pkg->name() << endl;
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
144
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
145
}
Lukas Appelhans's avatar
Lukas Appelhans committed
146

147
void QueryOperation::showChangelog(QList< Akabei::Package* > packages)
Lukas Appelhans's avatar
Lukas Appelhans committed
148 149 150 151 152 153 154
{
    if (packages.isEmpty())
        return;
    Akabei::Package * pkg = packages.first();
    QTextStream out(stdout);
    out << pkg->retrieveChangelog() << endl;
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
155
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
156 157 158 159 160 161 162
}

void QueryOperation::showInstalledAsDeps(QList<Akabei::Package*> packages)
{
    if (packages.isEmpty())
        return;
    QTextStream out(stdout);
163
    QMap<QString, Akabei::Package*> sorted;
Lukas Appelhans's avatar
Lukas Appelhans committed
164
    foreach (Akabei::Package * pkg, packages)
165 166
        sorted[pkg->name()] = pkg;
    foreach (Akabei::Package * pkg, sorted.values())
Lukas Appelhans's avatar
Lukas Appelhans committed
167 168
        out << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
169
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
170 171
}

172
void QueryOperation::checkFiles(QList<Akabei::Package*> packages)
Lukas Appelhans's avatar
Lukas Appelhans committed
173 174 175 176 177 178 179 180 181 182 183 184 185
{
    if (packages.isEmpty())
        return;
    Akabei::Package * pkg = packages.first();
    QTextStream out(stdout);
    int all = 0;
    int missing = 0;
    foreach (const QString &file, pkg->retrieveFiles()) {
        all++;
        if (!QFile::exists(Akabei::Config::instance()->rootDir().absoluteFilePath(file)))
            missing++;
    }
    out << pkg->name() << ": " << all << " overall files, " << missing << " file(s) missing" << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
186
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
187
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
}

void QueryOperation::showLocalPackages(const QString &query)
{
    QTextStream out(stdout);
    QList<Akabei::Package*> packages;
    if (!query.isEmpty())
        packages = Akabei::Backend::instance()->localDatabase()->searchPackages(query);
    else
        packages = Akabei::Backend::instance()->localDatabase()->packages();
    foreach (Akabei::Package* pkg, packages) {
        bool found = false;
        foreach (Akabei::Database* db, Akabei::Backend::instance()->databases()) {
            foreach (Akabei::Package* p, db->searchPackages(pkg->name())) {
                if (p->name() == pkg->name()) {
                    found = true;
                    break;
                }
            }
            if (found)
                break;
        }
        if (!found)
            out << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
    }
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
214
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
215 216
}

Lukas Appelhans's avatar
Lukas Appelhans committed
217 218 219 220 221 222
void QueryOperation::showOwner(const QString &query)
{
    QTextStream out(stdout);
    if (!QFile::exists(query)) {
        out << "File does not exists: " << query << endl;
        out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
223
        QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
224 225 226 227 228 229 230
        return;
    }
    foreach (Akabei::Package * pkg, Akabei::Backend::instance()->localDatabase()->packages()) {
        foreach (const QString &file, pkg->retrieveFiles()) {
            if (Akabei::Config::instance()->rootDir().absoluteFilePath(file) == query) {
                out << query  << " is owned by " << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
                out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
231
                QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
232 233 234 235 236 237
                return;
            }
        }
    }
    out << "Error: No packages owns " << query << endl;
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
238
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
239
}
Lukas Appelhans's avatar
Lukas Appelhans committed
240 241 242 243 244 245 246 247 248

void QueryOperation::showLocalQuery(QList<Akabei::Package*> packages)
{
    QTextStream out(stdout);
    QMap<QString, Akabei::Package*> sorted;
    foreach (Akabei::Package * pkg, packages)
        sorted[pkg->name()] = pkg;
    foreach (Akabei::Package * pkg, sorted.values()) {
        out << "local/" << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
249
        out << "\t" << pkg->description() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
250 251
    }
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
252
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
253
}
Lukas Appelhans's avatar
Lukas Appelhans committed
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268

void QueryOperation::showNotRequired()
{
    QTextStream out(stdout);
    QList<Akabei::Package*> packages = Akabei::Backend::instance()->localDatabase()->packages();
    QMap<QString, Akabei::Package*> pkgs;
    foreach (Akabei::Package* pkg, packages)
        pkgs[pkg->name()] = pkg;
    foreach (Akabei::Package* pkg, packages) {
        foreach (const QString &dep, pkg->dependencies())
            pkgs.remove(dep);
    }
    foreach (Akabei::Package * pkg, pkgs.values())
        out << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
269
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
270
}
Lukas Appelhans's avatar
Lukas Appelhans committed
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295

void QueryOperation::showUpgradeable()
{
    //FIXME: Maybe don't even check for the highest version... redundant?
    QTextStream out(stdout);
    QList<Akabei::Package*> packages = Akabei::Backend::instance()->localDatabase()->packages();
    QMap<QString, Akabei::Package*> upgradeable;
    foreach (Akabei::Package * pkg, packages) {
        foreach (Akabei::Database * db, Akabei::Backend::instance()->databases()) {
            Akabei::Package::List list = db->queryPackages("SELECT * FROM packages WHERE Name LIKE \"" + pkg->name() + "\"");
            if (!list.isEmpty()) {
                foreach (Akabei::Package * p, list) {
                    if (p->version() > pkg->version() && p->name() == pkg->name()) {
                        if (upgradeable[p->name()] && upgradeable[p->name()]->version() > p->version())
                            continue;
                        upgradeable[p->name()] = p;
                    }
                }
            }
        }
    }
    
    foreach (Akabei::Package * pkg, upgradeable.values())
        out << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
296
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
297
}