PageRenderTime 84ms CodeModel.GetById 20ms app.highlight 49ms RepoModel.GetById 11ms app.codeStats 1ms

/src/libtomahawk/database/DatabaseCommand_SetDynamicPlaylistRevision.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 271 lines | 213 code | 38 blank | 20 comment | 26 complexity | 891c6ff535e1cd026504eba05346a7fc MD5 | raw file
  1/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2 *
  3 *   Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
  4 *
  5 *   Tomahawk is free software: you can redistribute it and/or modify
  6 *   it under the terms of the GNU General Public License as published by
  7 *   the Free Software Foundation, either version 3 of the License, or
  8 *   (at your option) any later version.
  9 *
 10 *   Tomahawk is distributed in the hope that it will be useful,
 11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 13 *   GNU General Public License for more details.
 14 *
 15 *   You should have received a copy of the GNU General Public License
 16 *   along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
 17 */
 18
 19#include "DatabaseCommand_SetDynamicPlaylistRevision.h"
 20
 21#include "collection/Collection.h"
 22#include "playlist/dynamic/DynamicPlaylist.h"
 23#include "playlist/dynamic/DynamicControl.h"
 24#include "network/Servent.h"
 25#include "utils/Json.h"
 26#include "utils/Logger.h"
 27
 28#include "DatabaseImpl.h"
 29#include "Source.h"
 30#include "TomahawkSqlQuery.h"
 31
 32#include <QSqlQuery>
 33
 34namespace Tomahawk
 35{
 36
 37DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision( const Tomahawk::source_ptr& s,
 38                                                                                const QString& playlistguid,
 39                                                                                const QString& newrev,
 40                                                                                const QString& oldrev,
 41                                                                                const QStringList& orderedguids,
 42                                                                                const QList< plentry_ptr >& addedentries,
 43                                                                                const QList<plentry_ptr>& entries,
 44                                                                                const QString& type,
 45                                                                                GeneratorMode mode,
 46                                                                                const QList< dyncontrol_ptr >& controls )
 47    : DatabaseCommand_SetPlaylistRevision( s, playlistguid, newrev, oldrev, orderedguids, addedentries, entries )
 48    , m_type( type )
 49    , m_mode( mode )
 50    , m_controls( controls )
 51    , m_playlist( 0 )
 52{
 53
 54}
 55
 56
 57DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision( const Tomahawk::source_ptr& s,
 58                                                                                const QString& playlistguid,
 59                                                                                const QString& newrev,
 60                                                                                const QString& oldrev,
 61                                                                                const QString& type,
 62                                                                                GeneratorMode mode,
 63                                                                                const QList< dyncontrol_ptr >& controls )
 64    : DatabaseCommand_SetPlaylistRevision( s, playlistguid, newrev, oldrev, QStringList(), QList< plentry_ptr >(), QList< plentry_ptr >() )
 65    , m_type( type )
 66    , m_mode( mode )
 67    , m_controls( controls )
 68    , m_playlist( 0 )
 69{
 70
 71}
 72
 73
 74QVariantList
 75DatabaseCommand_SetDynamicPlaylistRevision::controlsV()
 76{
 77    if ( m_controls.isEmpty() )
 78        return m_controlsV;
 79
 80    if ( !m_controls.isEmpty() && m_controlsV.isEmpty() )
 81    {
 82        foreach ( const dyncontrol_ptr& control, m_controls )
 83        {
 84            m_controlsV << TomahawkUtils::qobject2qvariant( control.data() );
 85        }
 86    }
 87
 88    return m_controlsV;
 89}
 90
 91
 92void
 93DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
 94{
 95    tDebug() << Q_FUNC_INFO;
 96    if ( source().isNull() || source()->dbCollection().isNull() )
 97    {
 98        tDebug() << "Source has gone offline, not emitting to GUI.";
 99        return;
100    }
101
102    QStringList orderedentriesguids;
103    foreach( const QVariant& v, orderedguids() )
104        orderedentriesguids << v.toString();
105
106    Q_ASSERT( !source().isNull() );
107    Q_ASSERT( !source()->dbCollection().isNull() );
108    tLog() << "Postcommitting this playlist:" << playlistguid() << source().isNull();
109
110    // private, but we are a friend. will recall itself in its own thread:
111    dynplaylist_ptr playlist = source()->dbCollection()->autoPlaylist( playlistguid() );
112    if ( playlist.isNull() )
113    {
114        playlist = source()->dbCollection()->station( playlistguid() );
115    }
116
117    if ( playlist.isNull() && !m_playlist.isNull() )
118    {
119        // if it's neither an auto or station, it must not be auto-loaded, so we MUST have been told about it directly
120        playlist = m_playlist;
121    }
122
123    if ( playlist.isNull() )
124    {
125        tLog() << "Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->dbCollection()->name() << "and mode is static?:" << (m_mode == Static);
126        return;
127    }
128
129    if ( !m_controlsV.isEmpty() && m_controls.isEmpty() )
130    {
131        QList<QVariantMap> controlMap;
132        foreach( const QVariant& v, m_controlsV )
133            controlMap << v.toMap();
134
135        if ( m_mode == OnDemand )
136            playlist->setRevision(  newrev(),
137                                    true, // this *is* the newest revision so far
138                                    m_type,
139                                    controlMap,
140                                    m_applied );
141        else
142            playlist->setRevision(  newrev(),
143                                    orderedentriesguids,
144                                    m_previous_rev_orderedguids,
145                                    m_type,
146                                    controlMap,
147                                    true, // this *is* the newest revision so far
148                                    m_addedmap,
149                                    m_applied );
150    }
151    else
152    {
153        if ( m_mode == OnDemand )
154            playlist->setRevision(  newrev(),
155                                    true, // this *is* the newest revision so far
156                                    m_type,
157                                    m_controls,
158                                    m_applied );
159        else
160            playlist->setRevision(  newrev(),
161                                    orderedentriesguids,
162                                    m_previous_rev_orderedguids,
163                                    m_type,
164                                    m_controls,
165                                    true, // this *is* the newest revision so far
166                                    m_addedmap,
167                                    m_applied );
168    }
169
170    if ( source()->isLocal() )
171        Servent::instance()->triggerDBSync();
172}
173
174
175void
176DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
177{
178    DatabaseCommand_SetPlaylistRevision::exec( lib );
179    if ( m_failed )
180        return;
181
182    QVariantList newcontrols;
183    if ( m_controlsV.isEmpty() && !m_controls.isEmpty() )
184    {
185        foreach( const dyncontrol_ptr& control, m_controls )
186        {
187            newcontrols << control->id();
188        }
189    }
190    else if( !m_controlsV.isEmpty() )
191    {
192        foreach( const QVariant& v, m_controlsV )
193        {
194            newcontrols << v.toMap().value( "id" );
195        }
196    }
197
198    const QByteArray newcontrols_data = TomahawkUtils::toJson( newcontrols );
199
200    TomahawkSqlQuery query = lib->newquery();
201    QString sql = "INSERT INTO dynamic_playlist_revision (guid, controls, plmode, pltype) "
202                  "VALUES(?, ?, ?, ?)";
203
204    query.prepare( sql );
205    query.addBindValue( m_newrev );
206    query.addBindValue( newcontrols_data );
207    query.addBindValue( QString::number( (int) m_mode ) );
208    query.addBindValue( m_type );
209    query.exec();
210
211    // delete all the old controls, replace with new onws
212    qDebug() << "Deleting controls with playlist id" << m_playlistguid;
213    TomahawkSqlQuery delQuery = lib->newquery();
214    delQuery.prepare( "DELETE FROM dynamic_playlist_controls WHERE playlist = ?" );
215    delQuery.addBindValue( m_playlistguid );
216    if ( !delQuery.exec() )
217        tLog() << "Failed to delete controls from dynamic playlist controls table";
218
219    TomahawkSqlQuery controlsQuery = lib->newquery();
220    controlsQuery.prepare( "INSERT INTO dynamic_playlist_controls( id, playlist, selectedType, match, input ) "
221                            "VALUES( ?, ?, ?, ?, ? )" );
222    if ( m_controlsV.isEmpty() && !m_controls.isEmpty() )
223    {
224        foreach ( const dyncontrol_ptr& control, m_controls )
225        {
226            qDebug() << "inserting dynamic control:" << control->id() << m_playlistguid << control->selectedType() << control->match() << control->input();
227            controlsQuery.addBindValue( control->id() );
228            controlsQuery.addBindValue( m_playlistguid );
229            controlsQuery.addBindValue( control->selectedType() );
230            controlsQuery.addBindValue( control->match() );
231            controlsQuery.addBindValue( control->input() );
232
233            controlsQuery.exec();
234        }
235    }
236    else
237    {
238        foreach ( const QVariant& v, m_controlsV )
239        {
240            QVariantMap control = v.toMap();
241            qDebug() << "inserting dynamic control from JSON:" << control.value( "id" ) << m_playlistguid << control.value( "selectedType" ) << control.value( "match" ) << control.value( "input" );
242            controlsQuery.addBindValue( control.value( "id" ) );
243            controlsQuery.addBindValue( m_playlistguid );
244            controlsQuery.addBindValue( control.value( "selectedType" ) );
245            controlsQuery.addBindValue( control.value( "match" ) );
246            controlsQuery.addBindValue( control.value( "input" ) );
247
248            controlsQuery.exec();
249        }
250    }
251
252    if ( m_applied )
253    {
254        tLog() << "updating dynamic playlist, optimistic locking okay";
255
256        TomahawkSqlQuery query2 = lib->newquery();
257        query2.prepare( "UPDATE dynamic_playlist SET pltype = ?, plmode = ? WHERE guid = ?" );
258        query2.bindValue( 0, m_type );
259        query2.bindValue( 1, m_mode );
260        query2.bindValue( 2, m_playlistguid );
261        query2.exec();
262    }
263}
264
265void
266DatabaseCommand_SetDynamicPlaylistRevision::setPlaylist( QWeakPointer<DynamicPlaylist> pl )
267{
268    m_playlist = pl.toStrongRef();
269}
270
271}