File indexing completed on 2024-05-19 04:49:27

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com>            *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) any later           *
0007  * version.                                                                             *
0008  *                                                                                      *
0009  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0010  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0011  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0012  *                                                                                      *
0013  * You should have received a copy of the GNU General Public License along with         *
0014  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0015  ****************************************************************************************/
0016 
0017 #include "core/collections/MetaQueryMaker.h"
0018 #include "core/meta/Meta.h"
0019 
0020 using namespace Collections;
0021 
0022 MetaQueryMaker::MetaQueryMaker( const QList<Collections::Collection*> &collections )
0023     : QueryMaker()
0024     , m_queryDoneCount( 0 )
0025     , m_queryDoneCountMutex()
0026 {
0027     foreach( Collections::Collection *c, collections )
0028     {
0029         QueryMaker *b = c->queryMaker();
0030         builders.append( b );
0031         connect( b, &QueryMaker::queryDone, this, &MetaQueryMaker::slotQueryDone );
0032         //relay signals directly
0033         // actually this is wrong. We would need to combine the results
0034         // to prevent duplicate album name results.
0035         // On the other hand we need duplicate AlbumPtr results.
0036         // Summary: be careful when using this class. (Ralf)
0037         connect( b, &QueryMaker::newTracksReady, this, &MetaQueryMaker::newTracksReady, Qt::DirectConnection );
0038         connect( b, &QueryMaker::newArtistsReady, this, &MetaQueryMaker::newArtistsReady, Qt::DirectConnection );
0039         connect( b, &QueryMaker::newAlbumsReady, this, &MetaQueryMaker::newAlbumsReady, Qt::DirectConnection );
0040         connect( b, &QueryMaker::newGenresReady, this, &MetaQueryMaker::newGenresReady, Qt::DirectConnection );
0041         connect( b, &QueryMaker::newComposersReady, this, &MetaQueryMaker::newComposersReady, Qt::DirectConnection );
0042         connect( b, &QueryMaker::newYearsReady, this, &MetaQueryMaker::newYearsReady, Qt::DirectConnection );
0043         connect( b, &QueryMaker::newResultReady, this, &MetaQueryMaker::newResultReady, Qt::DirectConnection );
0044         connect( b, &QueryMaker::newLabelsReady, this, &MetaQueryMaker::newLabelsReady, Qt::DirectConnection );
0045     }
0046 }
0047 
0048 MetaQueryMaker::MetaQueryMaker( const QList<QueryMaker*> &queryMakers )
0049     : QueryMaker()
0050     , builders( queryMakers )
0051     , m_queryDoneCount( 0 )
0052     , m_queryDoneCountMutex()
0053 {
0054     foreach( QueryMaker *b, builders )
0055     {
0056         connect( b, &QueryMaker::queryDone, this, &MetaQueryMaker::slotQueryDone );
0057         //relay signals directly
0058         connect( b, &QueryMaker::newTracksReady, this, &MetaQueryMaker::newTracksReady, Qt::DirectConnection );
0059         connect( b, &QueryMaker::newArtistsReady, this, &MetaQueryMaker::newArtistsReady, Qt::DirectConnection );
0060         connect( b, &QueryMaker::newAlbumsReady, this, &MetaQueryMaker::newAlbumsReady, Qt::DirectConnection );
0061         connect( b, &QueryMaker::newGenresReady, this, &MetaQueryMaker::newGenresReady, Qt::DirectConnection );
0062         connect( b, &QueryMaker::newComposersReady, this, &MetaQueryMaker::newComposersReady, Qt::DirectConnection );
0063         connect( b, &QueryMaker::newYearsReady, this, &MetaQueryMaker::newYearsReady, Qt::DirectConnection );
0064         connect( b, &QueryMaker::newResultReady, this, &MetaQueryMaker::newResultReady, Qt::DirectConnection );
0065         connect( b, &QueryMaker::newLabelsReady, this, &MetaQueryMaker::newLabelsReady, Qt::DirectConnection );
0066     }
0067 }
0068 
0069 MetaQueryMaker::~MetaQueryMaker()
0070 {
0071     foreach( QueryMaker *b, builders )
0072         delete b;
0073 }
0074 
0075 void
0076 MetaQueryMaker::run()
0077 {
0078     foreach( QueryMaker *b, builders )
0079         b->run();
0080 }
0081 
0082 void
0083 MetaQueryMaker::abortQuery()
0084 {
0085     foreach( QueryMaker *b, builders )
0086         b->abortQuery();
0087 }
0088 
0089 QueryMaker*
0090 MetaQueryMaker::setQueryType( QueryType type )
0091 {
0092     foreach( QueryMaker *qm, builders )
0093         qm->setQueryType( type );
0094     return this;
0095 }
0096 
0097 QueryMaker*
0098 MetaQueryMaker::addReturnValue( qint64 value )
0099 {
0100     foreach( QueryMaker *b, builders )
0101         b->addReturnValue( value );
0102     return this;
0103 }
0104 
0105 QueryMaker*
0106 MetaQueryMaker::addReturnFunction( ReturnFunction function, qint64 value )
0107 {
0108     foreach( QueryMaker *qm, builders )
0109         qm->addReturnFunction( function, value );
0110     return this;
0111 }
0112 
0113 /* Ok. That doesn't work. First connecting the signals directly and then
0114    doing "orderBy" directly */
0115 QueryMaker*
0116 MetaQueryMaker::orderBy( qint64 value, bool descending )
0117 {
0118     foreach( QueryMaker *b, builders )
0119         b->orderBy( value, descending );
0120     return this;
0121 }
0122 
0123 QueryMaker*
0124 MetaQueryMaker::addFilter( qint64 value, const QString &filter, bool matchBegin, bool matchEnd )
0125 {
0126     foreach( QueryMaker *b, builders )
0127         b->addFilter( value, filter, matchBegin, matchEnd );
0128     return this;
0129 }
0130 
0131 QueryMaker*
0132 MetaQueryMaker::excludeFilter( qint64 value, const QString &filter, bool matchBegin, bool matchEnd )
0133 {
0134     foreach( QueryMaker *b, builders )
0135         b->excludeFilter( value, filter, matchBegin, matchEnd );
0136     return this;
0137 }
0138 
0139 QueryMaker*
0140 MetaQueryMaker::addNumberFilter( qint64 value, qint64 filter, QueryMaker::NumberComparison compare )
0141 {
0142     foreach( QueryMaker *b, builders )
0143         b->addNumberFilter( value, filter, compare);
0144     return this;
0145 }
0146 
0147 QueryMaker*
0148 MetaQueryMaker::excludeNumberFilter( qint64 value, qint64 filter, QueryMaker::NumberComparison compare )
0149 {
0150     foreach( QueryMaker *b, builders )
0151         b->excludeNumberFilter( value, filter, compare );
0152     return this;
0153 }
0154 
0155 QueryMaker*
0156 MetaQueryMaker::addMatch( const Meta::TrackPtr &track )
0157 {
0158     foreach( QueryMaker *b, builders )
0159         b->addMatch( track );
0160     return this;
0161 }
0162 
0163 
0164 QueryMaker*
0165 MetaQueryMaker::addMatch( const Meta::ArtistPtr &artist, QueryMaker::ArtistMatchBehaviour behaviour )
0166 {
0167     foreach( QueryMaker *b, builders )
0168         b->addMatch( artist, behaviour );
0169     return this;
0170 }
0171 
0172 QueryMaker*
0173 MetaQueryMaker::addMatch( const Meta::AlbumPtr &album )
0174 {
0175     foreach( QueryMaker *b, builders )
0176         b->addMatch( album );
0177     return this;
0178 }
0179 
0180 QueryMaker*
0181 MetaQueryMaker::addMatch( const Meta::GenrePtr &genre )
0182 {
0183     foreach( QueryMaker *b, builders )
0184         b->addMatch( genre );
0185     return this;
0186 }
0187 
0188 QueryMaker*
0189 MetaQueryMaker::addMatch( const Meta::ComposerPtr &composer )
0190 {
0191     foreach( QueryMaker *b, builders )
0192         b->addMatch( composer );
0193     return this;
0194 }
0195 
0196 QueryMaker*
0197 MetaQueryMaker::addMatch( const Meta::YearPtr &year )
0198 {
0199     foreach( QueryMaker *b, builders )
0200         b->addMatch( year );
0201     return this;
0202 }
0203 
0204 QueryMaker*
0205 MetaQueryMaker::addMatch( const Meta::LabelPtr &label )
0206 {
0207     foreach( QueryMaker *b, builders )
0208         b->addMatch( label );
0209     return this;
0210 }
0211 
0212 QueryMaker*
0213 MetaQueryMaker::limitMaxResultSize( int size )
0214 {
0215     foreach( QueryMaker *b, builders )
0216         b->limitMaxResultSize( size );
0217     return this;
0218 }
0219 
0220 QueryMaker*
0221 MetaQueryMaker::beginAnd()
0222 {
0223     foreach( QueryMaker *b, builders )
0224         b->beginAnd();
0225     return this;
0226 }
0227 
0228 QueryMaker*
0229 MetaQueryMaker::beginOr()
0230 {
0231     foreach( QueryMaker *b, builders )
0232         b->beginOr();
0233     return this;
0234 }
0235 
0236 QueryMaker*
0237 MetaQueryMaker::endAndOr()
0238 {
0239     foreach( QueryMaker *b, builders )
0240         b->endAndOr();
0241     return this;
0242 }
0243 
0244 QueryMaker*
0245 MetaQueryMaker::setAlbumQueryMode( AlbumQueryMode mode )
0246 {
0247     foreach( QueryMaker *qm, builders )
0248         qm->setAlbumQueryMode( mode );
0249     return this;
0250 }
0251 
0252 QueryMaker*
0253 MetaQueryMaker::setLabelQueryMode( LabelQueryMode mode )
0254 {
0255     foreach( QueryMaker *qm, builders )
0256         qm->setLabelQueryMode( mode );
0257     return this;
0258 }
0259 
0260 void
0261 MetaQueryMaker::slotQueryDone()
0262 {
0263     m_queryDoneCountMutex.lock();
0264     m_queryDoneCount++;
0265     if ( m_queryDoneCount == builders.size() )
0266     {
0267         //make sure we don't give control to code outside this class while holding the lock
0268         m_queryDoneCountMutex.unlock();
0269         Q_EMIT queryDone();
0270     }
0271     else
0272         m_queryDoneCountMutex.unlock();
0273 }
0274 
0275