/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. #include "DatabaseCommand_SetDynamicPlaylistRevision.h"
  19. #include "collection/Collection.h"
  20. #include "playlist/dynamic/DynamicPlaylist.h"
  21. #include "playlist/dynamic/DynamicControl.h"
  22. #include "network/Servent.h"
  23. #include "utils/Json.h"
  24. #include "utils/Logger.h"
  25. #include "DatabaseImpl.h"
  26. #include "Source.h"
  27. #include "TomahawkSqlQuery.h"
  28. #include <QSqlQuery>
  29. namespace Tomahawk
  30. {
  31. DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision( const Tomahawk::source_ptr& s,
  32. const QString& playlistguid,
  33. const QString& newrev,
  34. const QString& oldrev,
  35. const QStringList& orderedguids,
  36. const QList< plentry_ptr >& addedentries,
  37. const QList<plentry_ptr>& entries,
  38. const QString& type,
  39. GeneratorMode mode,
  40. const QList< dyncontrol_ptr >& controls )
  41. : DatabaseCommand_SetPlaylistRevision( s, playlistguid, newrev, oldrev, orderedguids, addedentries, entries )
  42. , m_type( type )
  43. , m_mode( mode )
  44. , m_controls( controls )
  45. , m_playlist( 0 )
  46. {
  47. }
  48. DatabaseCommand_SetDynamicPlaylistRevision::DatabaseCommand_SetDynamicPlaylistRevision( const Tomahawk::source_ptr& s,
  49. const QString& playlistguid,
  50. const QString& newrev,
  51. const QString& oldrev,
  52. const QString& type,
  53. GeneratorMode mode,
  54. const QList< dyncontrol_ptr >& controls )
  55. : DatabaseCommand_SetPlaylistRevision( s, playlistguid, newrev, oldrev, QStringList(), QList< plentry_ptr >(), QList< plentry_ptr >() )
  56. , m_type( type )
  57. , m_mode( mode )
  58. , m_controls( controls )
  59. , m_playlist( 0 )
  60. {
  61. }
  62. QVariantList
  63. DatabaseCommand_SetDynamicPlaylistRevision::controlsV()
  64. {
  65. if ( m_controls.isEmpty() )
  66. return m_controlsV;
  67. if ( !m_controls.isEmpty() && m_controlsV.isEmpty() )
  68. {
  69. foreach ( const dyncontrol_ptr& control, m_controls )
  70. {
  71. m_controlsV << TomahawkUtils::qobject2qvariant( control.data() );
  72. }
  73. }
  74. return m_controlsV;
  75. }
  76. void
  77. DatabaseCommand_SetDynamicPlaylistRevision::postCommitHook()
  78. {
  79. tDebug() << Q_FUNC_INFO;
  80. if ( source().isNull() || source()->dbCollection().isNull() )
  81. {
  82. tDebug() << "Source has gone offline, not emitting to GUI.";
  83. return;
  84. }
  85. QStringList orderedentriesguids;
  86. foreach( const QVariant& v, orderedguids() )
  87. orderedentriesguids << v.toString();
  88. Q_ASSERT( !source().isNull() );
  89. Q_ASSERT( !source()->dbCollection().isNull() );
  90. tLog() << "Postcommitting this playlist:" << playlistguid() << source().isNull();
  91. // private, but we are a friend. will recall itself in its own thread:
  92. dynplaylist_ptr playlist = source()->dbCollection()->autoPlaylist( playlistguid() );
  93. if ( playlist.isNull() )
  94. {
  95. playlist = source()->dbCollection()->station( playlistguid() );
  96. }
  97. if ( playlist.isNull() && !m_playlist.isNull() )
  98. {
  99. // if it's neither an auto or station, it must not be auto-loaded, so we MUST have been told about it directly
  100. playlist = m_playlist;
  101. }
  102. if ( playlist.isNull() )
  103. {
  104. tLog() << "Got null playlist with guid:" << playlistguid() << "from source and collection:" << source()->friendlyName() << source()->dbCollection()->name() << "and mode is static?:" << (m_mode == Static);
  105. return;
  106. }
  107. if ( !m_controlsV.isEmpty() && m_controls.isEmpty() )
  108. {
  109. QList<QVariantMap> controlMap;
  110. foreach( const QVariant& v, m_controlsV )
  111. controlMap << v.toMap();
  112. if ( m_mode == OnDemand )
  113. playlist->setRevision( newrev(),
  114. true, // this *is* the newest revision so far
  115. m_type,
  116. controlMap,
  117. m_applied );
  118. else
  119. playlist->setRevision( newrev(),
  120. orderedentriesguids,
  121. m_previous_rev_orderedguids,
  122. m_type,
  123. controlMap,
  124. true, // this *is* the newest revision so far
  125. m_addedmap,
  126. m_applied );
  127. }
  128. else
  129. {
  130. if ( m_mode == OnDemand )
  131. playlist->setRevision( newrev(),
  132. true, // this *is* the newest revision so far
  133. m_type,
  134. m_controls,
  135. m_applied );
  136. else
  137. playlist->setRevision( newrev(),
  138. orderedentriesguids,
  139. m_previous_rev_orderedguids,
  140. m_type,
  141. m_controls,
  142. true, // this *is* the newest revision so far
  143. m_addedmap,
  144. m_applied );
  145. }
  146. if ( source()->isLocal() )
  147. Servent::instance()->triggerDBSync();
  148. }
  149. void
  150. DatabaseCommand_SetDynamicPlaylistRevision::exec( DatabaseImpl* lib )
  151. {
  152. DatabaseCommand_SetPlaylistRevision::exec( lib );
  153. if ( m_failed )
  154. return;
  155. QVariantList newcontrols;
  156. if ( m_controlsV.isEmpty() && !m_controls.isEmpty() )
  157. {
  158. foreach( const dyncontrol_ptr& control, m_controls )
  159. {
  160. newcontrols << control->id();
  161. }
  162. }
  163. else if( !m_controlsV.isEmpty() )
  164. {
  165. foreach( const QVariant& v, m_controlsV )
  166. {
  167. newcontrols << v.toMap().value( "id" );
  168. }
  169. }
  170. const QByteArray newcontrols_data = TomahawkUtils::toJson( newcontrols );
  171. TomahawkSqlQuery query = lib->newquery();
  172. QString sql = "INSERT INTO dynamic_playlist_revision (guid, controls, plmode, pltype) "
  173. "VALUES(?, ?, ?, ?)";
  174. query.prepare( sql );
  175. query.addBindValue( m_newrev );
  176. query.addBindValue( newcontrols_data );
  177. query.addBindValue( QString::number( (int) m_mode ) );
  178. query.addBindValue( m_type );
  179. query.exec();
  180. // delete all the old controls, replace with new onws
  181. qDebug() << "Deleting controls with playlist id" << m_playlistguid;
  182. TomahawkSqlQuery delQuery = lib->newquery();
  183. delQuery.prepare( "DELETE FROM dynamic_playlist_controls WHERE playlist = ?" );
  184. delQuery.addBindValue( m_playlistguid );
  185. if ( !delQuery.exec() )
  186. tLog() << "Failed to delete controls from dynamic playlist controls table";
  187. TomahawkSqlQuery controlsQuery = lib->newquery();
  188. controlsQuery.prepare( "INSERT INTO dynamic_playlist_controls( id, playlist, selectedType, match, input ) "
  189. "VALUES( ?, ?, ?, ?, ? )" );
  190. if ( m_controlsV.isEmpty() && !m_controls.isEmpty() )
  191. {
  192. foreach ( const dyncontrol_ptr& control, m_controls )
  193. {
  194. qDebug() << "inserting dynamic control:" << control->id() << m_playlistguid << control->selectedType() << control->match() << control->input();
  195. controlsQuery.addBindValue( control->id() );
  196. controlsQuery.addBindValue( m_playlistguid );
  197. controlsQuery.addBindValue( control->selectedType() );
  198. controlsQuery.addBindValue( control->match() );
  199. controlsQuery.addBindValue( control->input() );
  200. controlsQuery.exec();
  201. }
  202. }
  203. else
  204. {
  205. foreach ( const QVariant& v, m_controlsV )
  206. {
  207. QVariantMap control = v.toMap();
  208. qDebug() << "inserting dynamic control from JSON:" << control.value( "id" ) << m_playlistguid << control.value( "selectedType" ) << control.value( "match" ) << control.value( "input" );
  209. controlsQuery.addBindValue( control.value( "id" ) );
  210. controlsQuery.addBindValue( m_playlistguid );
  211. controlsQuery.addBindValue( control.value( "selectedType" ) );
  212. controlsQuery.addBindValue( control.value( "match" ) );
  213. controlsQuery.addBindValue( control.value( "input" ) );
  214. controlsQuery.exec();
  215. }
  216. }
  217. if ( m_applied )
  218. {
  219. tLog() << "updating dynamic playlist, optimistic locking okay";
  220. TomahawkSqlQuery query2 = lib->newquery();
  221. query2.prepare( "UPDATE dynamic_playlist SET pltype = ?, plmode = ? WHERE guid = ?" );
  222. query2.bindValue( 0, m_type );
  223. query2.bindValue( 1, m_mode );
  224. query2.bindValue( 2, m_playlistguid );
  225. query2.exec();
  226. }
  227. }
  228. void
  229. DatabaseCommand_SetDynamicPlaylistRevision::setPlaylist( QWeakPointer<DynamicPlaylist> pl )
  230. {
  231. m_playlist = pl.toStrongRef();
  232. }
  233. }