File indexing completed on 2025-01-19 03:53:40

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2007-03-22
0007  * Description : Building complex database SQL queries from search descriptions
0008  *
0009  * SPDX-FileCopyrightText: 2005      by Renchi Raju <renchi dot raju at gmail dot com>
0010  * SPDX-FileCopyrightText: 2007-2012 by Marcel Wiesweg <marcel dot wiesweg at gmx dot de>
0011  * SPDX-FileCopyrightText: 2012-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0012  *
0013  * SPDX-License-Identifier: GPL-2.0-or-later
0014  *
0015  * ============================================================ */
0016 
0017 #include "itemquerybuilder_p.h"
0018 
0019 namespace Digikam
0020 {
0021 
0022 RuleTypeForConversion::RuleTypeForConversion()
0023     : op(SearchXml::Equal)
0024 {
0025 }
0026 
0027 // -------------------------------------------------------------------
0028 
0029 QString SubQueryBuilder::build(enum SKey key,
0030                                enum SOperator op,
0031                                const QString& passedVal,
0032                                QList<QVariant>* boundValues) const
0033 {
0034     QString query;
0035     QString val = passedVal;
0036 
0037     if ((op == LIKE) || (op == NLIKE))
0038     {
0039         val = QLatin1Char('%') + val + QLatin1Char('%');
0040     }
0041 
0042     switch (key)
0043     {
0044         case (ALBUM):
0045         {
0046             query = QString::fromUtf8(" (Images.dirid $$##$$ ?) ");
0047             *boundValues << val;
0048             break;
0049         }
0050 
0051         case (ALBUMNAME):
0052         {
0053             query = QString::fromUtf8(" (Images.dirid IN "
0054                     "  (SELECT id FROM Albums WHERE url $$##$$ ?)) ");
0055             *boundValues << val;
0056             break;
0057         }
0058 
0059         case (ALBUMCAPTION):
0060         {
0061             query = QString::fromUtf8(" (Images.dirid IN "
0062                     "  (SELECT id FROM Albums WHERE caption $$##$$ ?)) ");
0063             *boundValues << val;
0064             break;
0065         }
0066 
0067         case (ALBUMCOLLECTION):
0068         {
0069             query = QString::fromUtf8(" (Images.dirid IN "
0070                     "  (SELECT id FROM Albums WHERE collection $$##$$ ?)) ");
0071             *boundValues << val;
0072             break;
0073         }
0074 
0075         case (TAG):
0076         {
0077             if      (op == EQ)
0078             {
0079                 query = QString::fromUtf8(" (Images.id IN "
0080                         "   (SELECT imageid FROM ImageTags "
0081                         "    WHERE tagid = ?)) ");
0082                 *boundValues << val.toInt();
0083             }
0084             else if (op == NE)
0085             {
0086                 query = QString::fromUtf8(" (Images.id NOT IN "
0087                         "   (SELECT imageid FROM ImageTags "
0088                         "    WHERE tagid = ?)) ");
0089                 *boundValues << val.toInt();
0090             }
0091             else if (op == LIKE)
0092             {
0093                 query = QString::fromUtf8(" (Images.id IN "
0094                         "   (SELECT ImageTags.imageid FROM ImageTags INNER JOIN TagsTree ON ImageTags.tagid = TagsTree.id "
0095                         "    WHERE TagsTree.pid = ? or ImageTags.tagid = ? )) ");
0096                 *boundValues << val.toInt() << val.toInt();
0097             }
0098             else // op == NLIKE
0099             {
0100                 query = QString::fromUtf8(" (Images.id NOT IN "
0101                         "   (SELECT ImageTags.imageid FROM ImageTags INNER JOIN TagsTree ON ImageTags.tagid = TagsTree.id "
0102                         "    WHERE TagsTree.pid = ? or ImageTags.tagid = ? )) ");
0103                 *boundValues << val.toInt() << val.toInt();
0104             }
0105 
0106             //         query = QString::fromUtf8(" (Images.id IN "
0107             //                 "   (SELECT imageid FROM ImageTags "
0108             //                 "    WHERE tagid $$##$$ ?)) ");
0109 
0110             break;
0111         }
0112 
0113         case (TAGNAME):
0114         {
0115             query = QString::fromUtf8(" (Images.id IN "
0116                     "  (SELECT imageid FROM ImageTags "
0117                     "   WHERE tagid IN "
0118                     "   (SELECT id FROM Tags WHERE name $$##$$ ?))) ");
0119             *boundValues << val;
0120             break;
0121         }
0122 
0123         case (IMAGENAME):
0124         {
0125             query = QString::fromUtf8(" (Images.name $$##$$ ?) ");
0126             *boundValues << val;
0127             break;
0128         }
0129 
0130         case (IMAGECAPTION):
0131         {
0132             query = QString::fromUtf8(" (Images.caption $$##$$ ?) ");
0133             *boundValues << val;
0134             break;
0135         }
0136 
0137         case (IMAGEDATE):
0138         {
0139             query = QString::fromUtf8(" (Images.datetime $$##$$ ?) ");
0140             *boundValues << val;
0141             break;
0142         }
0143 
0144         case (KEYWORD):
0145         {
0146             qCWarning(DIGIKAM_DATABASE_LOG) << "KEYWORD Detected which is not possible";
0147             break;
0148         }
0149 
0150         case (RATING):
0151         {
0152             query = QString::fromUtf8(" (ImageProperties.value $$##$$ ? and ImageProperties.property='Rating') ");
0153             *boundValues << val;
0154             break;
0155         }
0156     }
0157 
0158     if (key != TAG)
0159     {
0160         switch (op)
0161         {
0162             case (EQ):
0163             {
0164                 query.replace(QString::fromUtf8("$$##$$"), QString::fromUtf8("="));
0165                 break;
0166             }
0167 
0168             case (NE):
0169             {
0170                 query.replace(QString::fromUtf8("$$##$$"), QString::fromUtf8("<>"));
0171                 break;
0172             }
0173 
0174             case (LT):
0175             {
0176                 query.replace(QString::fromUtf8("$$##$$"), QString::fromUtf8("<"));
0177                 break;
0178             }
0179 
0180             case (GT):
0181             {
0182                 query.replace(QString::fromUtf8("$$##$$"), QString::fromUtf8(">"));
0183                 break;
0184             }
0185 
0186             case (LTE):
0187             {
0188                 query.replace(QString::fromUtf8("$$##$$"), QString::fromUtf8("<="));
0189                 break;
0190             }
0191 
0192             case (GTE):
0193             {
0194                 query.replace(QString::fromUtf8("$$##$$"), QString::fromUtf8(">="));
0195                 break;
0196             }
0197 
0198             case (LIKE):
0199             {
0200                 query.replace(QString::fromUtf8("$$##$$"), QString::fromUtf8("LIKE"));
0201                 break;
0202             }
0203 
0204             case (NLIKE):
0205             {
0206                 query.replace(QString::fromUtf8("$$##$$"), QString::fromUtf8("NOT LIKE"));
0207                 break;
0208             }
0209         }
0210     }
0211 
0212     // special case for imagedate. If the key is imagedate and the operator is EQ,
0213     // we need to split it into two rules
0214     if ((key == IMAGEDATE) && (op == EQ))
0215     {
0216         QDate date = QDate::fromString(val, Qt::ISODate);
0217 
0218         if (!date.isValid())
0219         {
0220             return query;
0221         }
0222 
0223         query = QString::fromUtf8(" (Images.datetime > ? AND Images.datetime < ?) ");
0224         *boundValues << date.addDays(-1).toString(Qt::ISODate)
0225                      << date.addDays( 1).toString(Qt::ISODate);
0226     }
0227 
0228     return query;
0229 }
0230 
0231 } // namespace Digikam