[banshee] [RandomBy] Refactor, removing duplication



commit 4f11b3ba00223dd3336d1205e49d1748d0d3555b
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Fri Nov 12 16:52:30 2010 -0600

    [RandomBy] Refactor, removing duplication
    
    We had separate methods in each RandomBy subclass for getting a playback
    track (meaning from the current source's track list, filtered by any
    active queries, and avoiding dupes based on what has been skipped and
    played) vs getting a shuffled track from an unfiltered source, avoiding
    dupes by using the CoreShuffles table (like Auto DJ does).

 .../Banshee.Collection.Database/RandomBy.cs        |   98 +++++++++++--------
 .../Banshee.Collection.Database/RandomByAlbum.cs   |   19 +---
 .../Banshee.Collection.Database/RandomByArtist.cs  |   14 +--
 .../Banshee.Collection.Database/RandomByOff.cs     |   12 +--
 .../Banshee.Collection.Database/RandomByRating.cs  |   19 +---
 .../Banshee.Collection.Database/RandomByScore.cs   |   26 ++----
 .../Banshee.Collection.Database/RandomBySlot.cs    |    1 +
 .../Banshee.Collection.Database/RandomByTrack.cs   |   13 +---
 .../Banshee.Collection.Database/Shuffler.cs        |   14 ++--
 9 files changed, 88 insertions(+), 128 deletions(-)
---
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomBy.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomBy.cs
index 7f9a169..76a323d 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomBy.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomBy.cs
@@ -27,6 +27,8 @@
 //
 
 using System;
+using System.Linq;
+using System.Collections.Generic;
 
 using Hyena;
 using Hyena.Data;
@@ -46,11 +48,12 @@ namespace Banshee.Collection.Database
     /// </summary>
     public abstract class RandomBy
     {
-        protected const string RANDOM_CONDITION = "AND LastStreamError = 0 AND (LastPlayedStamp < ? OR LastPlayedStamp IS NULL) AND (LastSkippedStamp < ? OR LastSkippedStamp IS NULL)";
-
         protected DatabaseTrackListModel Model { get; private set; }
         protected IDatabaseTrackModelCache Cache { get; private set; }
 
+        private HyenaSqliteCommand shuffler_query;
+        private string filtered_shuffler_condition;
+
         protected Shuffler Shuffler { get; private set; }
 
         public string Id { get; private set; }
@@ -79,7 +82,6 @@ namespace Banshee.Collection.Database
             Shuffler = shuffler;
         }
 
-        private HyenaSqliteCommand shuffler_query;
         protected HyenaSqliteCommand ShufflerQuery {
             get {
                 if (shuffler_query == null) {
@@ -102,6 +104,22 @@ namespace Banshee.Collection.Database
             }
         }
 
+        private string CacheCondition {
+            get {
+                if (filtered_shuffler_condition == null) {
+                    filtered_shuffler_condition = String.Format (@"
+                        AND {0}
+                        AND LastStreamError = 0
+                        AND (LastPlayedStamp < ? OR LastPlayedStamp IS NULL)
+                        AND (LastSkippedStamp < ? OR LastSkippedStamp IS NULL)
+                        ORDER BY {1}",
+                        Condition ?? "1=1", OrderBy
+                    );
+                }
+                return filtered_shuffler_condition;
+            }
+        }
+
         public void SetModelAndCache (DatabaseTrackListModel model, IDatabaseTrackModelCache cache)
         {
             if (Model != model) {
@@ -113,6 +131,7 @@ namespace Banshee.Collection.Database
             }
 
             shuffler_query = null;
+            filtered_shuffler_condition = null;
         }
 
         protected virtual void OnModelAndCacheUpdated ()
@@ -138,49 +157,46 @@ namespace Banshee.Collection.Database
 
         public TrackInfo GetTrack (DateTime after)
         {
-            if (Shuffler == Shuffler.Playback) {
-                return GetPlaybackTrack (after);
-            } else {
-                var track = GetShufflerTrack (after);
-
-                // Record this shuffle
-                Shuffler.RecordShuffle (track);
+            if (!IsReady) {
+                return null;
+            }
 
-                return track;
+            TrackInfo track = null;
+            using (var context = GetQueryContext (after)) {
+                var args = context.Parameters.ToList ();
+                args.Add (after);
+
+                if (Shuffler == Shuffler.Playback) {
+                    // Add a second after arg b/c we query against lastplay/lastskip stamps
+                    args.Add (after);
+                    track = Cache.GetSingle (Select, From, CacheCondition, args.ToArray ());
+                } else {
+                    track = GetTrack (ShufflerQuery, args.ToArray ());
+                }
             }
+
+            Shuffler.RecordShuffle (track as DatabaseTrackInfo);
+            return track;
         }
 
-        /// <summary>
-        /// Returns next Track to play in playback mode
-        /// </summary>
-        /// <param name="after">
-        /// A <see cref="DateTime"/>
-        /// </param>
-        /// <returns>
-        /// A <see cref="TrackInfo"/>
-        /// </returns>
-        /// <remarks>
-        /// When implementing this method, use Cache to query the model so user defined filters are respected
-        /// The playback track we choose is dependent on the current PlaybackSource, and what
-        /// (if any) query/filter is active there, represented by its DatabaseTrackModel (and its underlying cache).
-        ///
-        /// Remember to use RANDOM_CONDITION when using Cache, see other RandomBy Implementations for an Example
-        /// </remarks>
-        /// <see>RandomBy.Cache</see>
-        public abstract TrackInfo GetPlaybackTrack (DateTime after);
+        public class QueryContext : IDisposable
+        {
+            public QueryContext () {}
+            public virtual IEnumerable<object> Parameters { get; set; }
+            public virtual void Dispose () {}
+        }
 
-        /// <summary>
-        /// Returns Track to play in Shuffler Mode aka Auto-Dj
-        /// </summary>
-        /// <param name="after">
-        /// A <see cref="DateTime"/>
-        /// </param>
-        /// <returns>
-        /// A <see cref="DatabaseTrackInfo"/>
-        /// </returns>
-        /// <remarks>GetShufflerTrack should use the whole model to query a track</remarks>
-        /// <see>RandomBy.GetTrack</see>
-        public abstract DatabaseTrackInfo GetShufflerTrack (DateTime after);
+        protected virtual QueryContext GetQueryContext (DateTime after)
+        {
+            return new QueryContext () {
+                Parameters = GetConditionParameters (after)
+            };
+        }
+
+        protected virtual IEnumerable<object> GetConditionParameters (DateTime after)
+        {
+            yield break;
+        }
 
         protected DatabaseTrackInfo GetTrack (HyenaSqliteCommand cmd, params object [] args)
         {
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByAlbum.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByAlbum.cs
index 17398e9..7ab9928 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByAlbum.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByAlbum.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Collections.Generic;
 
 using Hyena;
 using Hyena.Data;
@@ -40,8 +41,6 @@ namespace Banshee.Collection.Database
 {
     public class RandomByAlbum : RandomBy
     {
-        private static string last_played_condition = String.Format ("AND CoreTracks.AlbumID = ? {0} ORDER BY Disc ASC, TrackNumber ASC", RANDOM_CONDITION);
-
         private HyenaSqliteCommand album_query;
         private int? album_id;
 
@@ -65,7 +64,9 @@ namespace Banshee.Collection.Database
             album_id = null;
         }
 
-        public override bool IsReady { get { return album_id != null; } }
+        public override bool IsReady {
+            get { return album_id != null; }
+        }
 
         public override bool Next (DateTime after)
         {
@@ -80,17 +81,9 @@ namespace Banshee.Collection.Database
             return IsReady;
         }
 
-        public override TrackInfo GetPlaybackTrack (DateTime after)
-        {
-            return album_id == null ? null : Cache.GetSingleWhere (last_played_condition, (int)album_id, after, after);
-        }
-
-        public override DatabaseTrackInfo GetShufflerTrack (DateTime after)
+        protected override IEnumerable<object> GetConditionParameters (DateTime after)
         {
-            if (album_id == null)
-                return null;
-
-            return GetTrack (ShufflerQuery, (int)album_id, after);
+            yield return album_id == null ? (int)0 : (int)album_id;
         }
 
         private HyenaSqliteCommand AlbumQuery {
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByArtist.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByArtist.cs
index d4e196b..63b0f53 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByArtist.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByArtist.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Collections.Generic;
 
 using Hyena;
 using Hyena.Data;
@@ -40,7 +41,6 @@ namespace Banshee.Collection.Database
 {
     public class RandomByArtist : RandomBy
     {
-        private static string track_condition = String.Format ("AND CoreAlbums.ArtistID = ? {0} ORDER BY CoreTracks.Year, CoreTracks.AlbumID ASC, Disc ASC, TrackNumber ASC", RANDOM_CONDITION);
         private HyenaSqliteCommand query;
         private int? id;
 
@@ -79,17 +79,9 @@ namespace Banshee.Collection.Database
             return IsReady;
         }
 
-        public override TrackInfo GetPlaybackTrack (DateTime after)
+        protected override IEnumerable<object> GetConditionParameters (DateTime after)
         {
-            return id == null ? null : Cache.GetSingleWhere (track_condition, (int)id, after, after);
-        }
-
-        public override DatabaseTrackInfo GetShufflerTrack (DateTime after)
-        {
-            if (id == null)
-                return null;
-
-            return GetTrack (ShufflerQuery, (int)id, after);
+            yield return id == null ? (int)0 : (int)id;
         }
 
         private HyenaSqliteCommand Query {
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByOff.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByOff.cs
index d0511c1..e5df18c 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByOff.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByOff.cs
@@ -25,6 +25,8 @@
 // THE SOFTWARE.
 
 using System;
+using System.Collections.Generic;
+
 using Mono.Unix;
 
 namespace Banshee.Collection.Database
@@ -45,16 +47,6 @@ namespace Banshee.Collection.Database
             return false;
         }
 
-        public override TrackInfo GetPlaybackTrack (DateTime after)
-        {
-            return null;
-        }
-
-        public override DatabaseTrackInfo GetShufflerTrack (DateTime after)
-        {
-            return null;
-        }
-
         #endregion
     }
 }
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByRating.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByRating.cs
index 57e61d3..6d2c882 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByRating.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByRating.cs
@@ -31,6 +31,7 @@
 //
 
 using System;
+using System.Collections.Generic;
 
 using Banshee.PlaybackController;
 using Mono.Unix;
@@ -39,8 +40,6 @@ namespace Banshee.Collection.Database
 {
     public class RandomByRating : RandomBySlot
     {
-        private static string track_condition = String.Format ("AND (CoreTracks.Rating = ? OR (? = 3 AND CoreTracks.Rating = 0)) {0} ORDER BY RANDOM()", RANDOM_CONDITION);
-
         public RandomByRating () : base ("rating")
         {
             Label = Catalog.GetString ("Shuffle by _Rating");
@@ -51,21 +50,11 @@ namespace Banshee.Collection.Database
             OrderBy = "RANDOM()";
         }
 
-        public override TrackInfo GetPlaybackTrack (DateTime after)
-        {
-            var track = !IsReady ? null : Cache.GetSingleWhere (track_condition, slot + 1, slot + 1, after, after);
-            Reset ();
-            return track;
-        }
-
-        public override DatabaseTrackInfo GetShufflerTrack (DateTime after)
+        protected override IEnumerable<object> GetConditionParameters (DateTime after)
         {
-            if (!IsReady)
-                return null;
-
-            var track = GetTrack (ShufflerQuery, slot + 1, slot + 1, after);
+            yield return slot + 1;
+            yield return slot + 1;
             Reset ();
-            return track;
         }
 
         protected override int Slots {
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByScore.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByScore.cs
index ec61ce6..28fda52 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByScore.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByScore.cs
@@ -27,16 +27,16 @@
 //
 
 using System;
+using System.Collections.Generic;
 
-using Banshee.PlaybackController;
 using Mono.Unix;
 
+using Banshee.PlaybackController;
+
 namespace Banshee.Collection.Database
 {
     public class RandomByScore : RandomBySlot
     {
-        private static string track_condition = String.Format ("AND (CoreTracks.Score BETWEEN ? AND ? OR (? = 50 AND CoreTracks.Score = 0)) {0} ORDER BY RANDOM()", RANDOM_CONDITION);
-
         public RandomByScore () : base ("score")
         {
             Label = Catalog.GetString ("Shuffle by S_core");
@@ -47,27 +47,15 @@ namespace Banshee.Collection.Database
             OrderBy = "RANDOM()";
         }
 
-        public override TrackInfo GetPlaybackTrack (DateTime after)
-        {
-            int min = slot * 100 / Slots + 1;
-            int max = (slot + 1) * 100 / Slots;
-
-            var track = !IsReady ? null : Cache.GetSingleWhere (track_condition, min, max, max, after, after);
-            Reset ();
-            return track;
-        }
-
-        public override DatabaseTrackInfo GetShufflerTrack (DateTime after)
+        protected override IEnumerable<object> GetConditionParameters (DateTime after)
         {
-            if (!IsReady)
-                return null;
-
             int min = slot * 100 / Slots + 1;
             int max = (slot + 1) * 100 / Slots;
 
-            var track = GetTrack (ShufflerQuery, min, max, max, after);
+            yield return min;
+            yield return max;
+            yield return max;
             Reset ();
-            return track;
         }
 
         protected override int Slots {
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomBySlot.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomBySlot.cs
index 2adf6c2..9216888 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomBySlot.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomBySlot.cs
@@ -31,6 +31,7 @@
 //
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
 
 using Hyena;
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByTrack.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByTrack.cs
index 24b133f..6e7b4f5 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByTrack.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/RandomByTrack.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Collections.Generic;
 
 using Hyena;
 using Hyena.Data;
@@ -40,8 +41,6 @@ namespace Banshee.Collection.Database
 {
     public class RandomByTrack : RandomBy
     {
-        private static string track_condition = String.Format ("{0} ORDER BY RANDOM()", RANDOM_CONDITION);
-
         public RandomByTrack () : base ("song")
         {
             Label = Catalog.GetString ("Shuffle by _Song");
@@ -56,15 +55,5 @@ namespace Banshee.Collection.Database
         {
             return true;
         }
-
-        public override TrackInfo GetPlaybackTrack (DateTime after)
-        {
-            return Cache.GetSingleWhere (track_condition, after, after);
-        }
-
-        public override DatabaseTrackInfo GetShufflerTrack (DateTime after)
-        {
-            return GetTrack (ShufflerQuery, after);
-        }
     }
 }
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/Shuffler.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/Shuffler.cs
index 1ed10bc..efc3246 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/Shuffler.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/Shuffler.cs
@@ -71,18 +71,18 @@ namespace Banshee.Collection.Database
 
         public IList<RandomBy> RandomModes { get { return random_modes; } }
 
-        private Shuffler ()
-        {
-            random_modes = new List<RandomBy> ();
-            AddinManager.AddExtensionNodeHandler ("/Banshee/PlaybackController/ShuffleModes", OnExtensionChanged);
-        }
-
         public Shuffler (string id) : this ()
         {
             Id = id;
             LoadOrCreate ();
         }
 
+        private Shuffler ()
+        {
+            random_modes = new List<RandomBy> ();
+            AddinManager.AddExtensionNodeHandler ("/Banshee/PlaybackController/ShuffleModes", OnExtensionChanged);
+        }
+
         private void OnExtensionChanged (object o, ExtensionNodeEventArgs args)
         {
             var tnode = (TypeExtensionNode)args.ExtensionNode;
@@ -230,4 +230,4 @@ namespace Banshee.Collection.Database
             }
         }
     }
-}
\ No newline at end of file
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]