banshee r3425 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Collection src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Database src/Core/Banshee.Services/Banshee.Query src/Core/Banshee.Services/Banshee.SmartPlaylist src/Core/Banshee.Services/Banshee.Sources src/Core/Banshee.ThickClient/Banshee.Collection.Gui src/Core/Banshee.ThickClient/Banshee.SmartPlaylist.Gui src/Core/Banshee.ThickClient/Banshee.Sources.Gui src/Extensions/Banshee.Lastfm/Resources src/Libraries/Hyena/Hyena.Data src/Libraries/Hyena/Hyena.Data.Sqlite



Author: gburt
Date: Tue Mar 11 23:44:39 2008
New Revision: 3425
URL: http://svn.gnome.org/viewvc/banshee?rev=3425&view=rev

Log:
2008-03-11  Gabriel Burt  <gabriel burt gmail com>

	This commit cleans up and speeds up reloading.

	* src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs:
	* src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs:
	Listen for Selection.Changed event and reload the track model with the
	appropriate ReloadTrigger argument.

	* src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs:
	Add a Reload method that takes a ReloadTrigger argument identifying what
	caused the reload (user query, artist or album filter) so each can be
	handled optimally.  Should fix performance regressions introduced in
	yesterday's bug fixes.

	* src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs: If
	there is only one real item and it's selected, then AllSelected = true.

	* src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs:
	Add a bunch more indexes to CoreTracks.

	* src/Core/Banshee.Services/Banshee.Query/BansheeQuery.cs: Do not call
	lower() within ORDER BY fragments for track sorting.  This means it will
	be case sensitive for now.  Sqlite's lower() method doesn't work with
	non-LATIN characters, and it's slow.  We need to add columns where we
	store the result of lowercasing Album, Artist, and Title in C#.

	* src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs:
	Add a new Refresh method that actually regenerates the smart playlist
	entries, since this doesn't need to happen on every Reload.

	* src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs: Move the
	complicated Reload logic into the *ListDatabaseModels.  Get rid of
	FilteredDuration/FileSize properties.

	* src/Core/Banshee.Services/Banshee.Sources/Source.cs:
	* src/Core/Banshee.Services/Banshee.Sources/IFileSizeAggregator.cs:
	* src/Core/Banshee.Services/Banshee.Sources/IDurationAggregator.cs: Remove
	Filtered* properties - we never display both, so might was well not require it
	or bother to calculate the un-filtered version.

	* src/Libraries/Hyena/Hyena.Data/IFilterable.cs:  Remove Refilter method.

	* src/Core/Banshee.ThickClient/Banshee.Collection.Gui/TrackListView.cs:
	Fix bug with default sort column where it was based on your column order.

	* src/Core/Banshee.ThickClient/Banshee.SmartPlaylist.Gui/Editor.cs: Call
	new Refresh method on SmartPlaylistSources.

	* src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs:
	Remove selection-changed source reload code - that's handled internally by the
	*ListDatabaseModels now.

	* src/Libraries/Hyena/Hyena.Data/ModelCache.cs: Change Reload to return
	void.

	* src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs: Use slightly
	faster INSERT INTO pattern, and don't automatically Save/RestoreSelection
	and UpdateAggregates within Reload.


Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Query/BansheeQuery.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/IDurationAggregator.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/IFileSizeAggregator.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/TrackListView.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.SmartPlaylist.Gui/Editor.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
   trunk/banshee/src/Extensions/Banshee.Lastfm/Resources/tag.png
   trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Data/IFilterable.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Data/ModelCache.cs

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs	Tue Mar 11 23:44:39 2008
@@ -32,6 +32,7 @@
 using System.Text;
 using System.Collections.Generic;
 
+using Hyena;
 using Hyena.Data.Sqlite;
 
 using Banshee.Database;
@@ -55,6 +56,8 @@
             provider = LibraryAlbumInfo.Provider;
             cache = new BansheeModelCache <LibraryAlbumInfo> (connection, uuid, this, provider);
             cache.HasSelectAllItem = true;
+
+            Selection.Changed += HandleSelectionChanged;
         }
 
         public AlbumListDatabaseModel (TrackListDatabaseModel trackModel, ArtistListDatabaseModel artistModel,
@@ -64,54 +67,48 @@
             this.artist_model = artistModel;
         }
 
-        private bool first_reload = true;
-        public override void Reload ()
+        private void HandleSelectionChanged (object sender, EventArgs args)
         {
-            Reload (false, true);
+            track_model.Reload (ReloadTrigger.AlbumFilter);
         }
 
-        public void Reload (bool unfiltered, bool notify)
+        public override void Reload ()
         {
-            TrackListDatabaseModel track_model = unfiltered ? null : this.track_model;
-            ArtistListDatabaseModel artist_model = unfiltered ? null : this.artist_model;
-
-            if (!first_reload || !cache.Warm) {
-                ArtistInfoFilter = artist_model == null ? null : artist_model.SelectedItems;
+            ArtistInfoFilter = artist_model == null ? null : artist_model.SelectedItems;
 
-                bool either = (artist_id_filter_query != null) || (track_model != null);
-                bool both = (artist_id_filter_query != null) && (track_model != null);
+            bool either = (artist_id_filter_query != null) || (track_model != null);
+            bool both = (artist_id_filter_query != null) && (track_model != null);
 
-                reload_fragment = String.Format (@"
-                    FROM CoreAlbums INNER JOIN CoreArtists ON CoreAlbums.ArtistID = CoreArtists.ArtistID
-                        {0} {1} {2} {3} ORDER BY CoreAlbums.Title, CoreArtists.Name",
-                    either ? "WHERE" : null,
-                    track_model == null ? null :
-                        String.Format (@"
-                            CoreAlbums.AlbumID IN
-                                (SELECT CoreTracks.AlbumID FROM CoreTracks, CoreCache{1}
-                                    WHERE CoreCache.ModelID = {0} AND
-                                          CoreCache.ItemId = {2})",
-                            track_model.CacheId,
-                            track_model.CachesJoinTableEntries ? track_model.JoinFragment : null,
-                            (!track_model.CachesJoinTableEntries)
-                                ? "CoreTracks.TrackID"
-                                : String.Format ("{0}.{1} AND CoreTracks.TrackID = {0}.{2}", track_model.JoinTable, track_model.JoinPrimaryKey, track_model.JoinColumn)
-                            ),
-                    both ? "AND" : null,
-                    artist_id_filter_query
-                );
-                //Console.WriteLine ("reload fragment for albums is {0}", reload_fragment);
-
-                cache.Reload ();
-            }
+            reload_fragment = String.Format (@"
+                FROM CoreAlbums INNER JOIN CoreArtists ON CoreAlbums.ArtistID = CoreArtists.ArtistID
+                    {0} {1} {2} {3} ORDER BY CoreAlbums.Title, CoreArtists.Name",
+                either ? "WHERE" : null,
+                track_model == null ? null :
+                    String.Format (@"
+                        CoreAlbums.AlbumID IN
+                            (SELECT CoreTracks.AlbumID FROM CoreTracks, CoreCache{1}
+                                WHERE CoreCache.ModelID = {0} AND
+                                      CoreCache.ItemId = {2})",
+                        track_model.CacheId,
+                        track_model.CachesJoinTableEntries ? track_model.JoinFragment : null,
+                        (!track_model.CachesJoinTableEntries)
+                            ? "CoreTracks.TrackID"
+                            : String.Format ("{0}.{1} AND CoreTracks.TrackID = {0}.{2}", track_model.JoinTable, track_model.JoinPrimaryKey, track_model.JoinColumn)
+                        ),
+                both ? "AND" : null,
+                artist_id_filter_query
+            );
+            //Console.WriteLine ("reload fragment for albums is {0}", reload_fragment);
+
+            cache.SaveSelection ();
+            cache.Reload ();
+            cache.UpdateAggregates ();
+            cache.RestoreSelection ();
 
-            first_reload = false;
             count = cache.Count + 1;
             select_all_album.Title = String.Format ("All Albums ({0})", count - 1);
 
-            if (notify) {
-                OnReloaded ();
-            }
+            OnReloaded ();
         }
         
         public override AlbumInfo this[int index] {

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs	Tue Mar 11 23:44:39 2008
@@ -31,6 +31,7 @@
 using System.Data;
 using System.Collections.Generic;
 
+using Hyena;
 using Hyena.Data.Sqlite;
 
 using Banshee.Database;
@@ -52,49 +53,46 @@
             provider = LibraryArtistInfo.Provider;
             cache = new BansheeModelCache <LibraryArtistInfo> (connection, uuid, this, provider);
             cache.HasSelectAllItem = true;
+
+            Selection.Changed += HandleSelectionChanged;
         }
 
         public ArtistListDatabaseModel(TrackListDatabaseModel trackModel, BansheeDbConnection connection, string uuid) : this (connection, uuid)
         {
             this.track_model = trackModel;
         }
-    
-        private bool first_reload = true;
-        public override void Reload ()
+
+        private void HandleSelectionChanged (object sender, EventArgs args)
         {
-            Reload (false, true);
+            track_model.Reload (ReloadTrigger.ArtistFilter);
         }
-
-        public void Reload (bool unfiltered, bool notify)
+    
+        public override void Reload ()
         {
-            TrackListDatabaseModel track_model = unfiltered ? null : this.track_model;
-
-            if (!first_reload || !cache.Warm) {
-                reload_fragment = String.Format (
-                    "FROM CoreArtists {0} ORDER BY Name",
-                    track_model == null ? null : String.Format (@"
-                        WHERE CoreArtists.ArtistID IN
-                            (SELECT CoreTracks.ArtistID FROM CoreTracks, CoreCache{1}
-                                WHERE CoreCache.ModelID = {0} AND
-                                      CoreCache.ItemID = {2})",
-                        track_model.CacheId,
-                        track_model.CachesJoinTableEntries ? track_model.JoinFragment : null,
-                        (!track_model.CachesJoinTableEntries)
-                            ? "CoreTracks.TrackID"
-                            : String.Format ("{0}.{1} AND CoreTracks.TrackID = {0}.{2}", track_model.JoinTable, track_model.JoinPrimaryKey, track_model.JoinColumn)
-                    )
-                );
+            reload_fragment = String.Format (
+                "FROM CoreArtists {0} ORDER BY Name",
+                track_model == null ? null : String.Format (@"
+                    WHERE CoreArtists.ArtistID IN
+                        (SELECT CoreTracks.ArtistID FROM CoreTracks, CoreCache{1}
+                            WHERE CoreCache.ModelID = {0} AND
+                                  CoreCache.ItemID = {2})",
+                    track_model.CacheId,
+                    track_model.CachesJoinTableEntries ? track_model.JoinFragment : null,
+                    (!track_model.CachesJoinTableEntries)
+                        ? "CoreTracks.TrackID"
+                        : String.Format ("{0}.{1} AND CoreTracks.TrackID = {0}.{2}", track_model.JoinTable, track_model.JoinPrimaryKey, track_model.JoinColumn)
+                )
+            );
+
+            cache.SaveSelection ();
+            cache.Reload ();
+            cache.UpdateAggregates ();
+            cache.RestoreSelection ();
 
-                cache.Reload ();
-            }
-
-            first_reload = false;
             count = cache.Count + 1;
             select_all_artist.Name = String.Format("All Artists ({0})", count - 1);
 
-            if (notify) {
-                OnReloaded();
-            }
+            OnReloaded();
         }
         
         public override ArtistInfo this[int index] {

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs	Tue Mar 11 23:44:39 2008
@@ -33,6 +33,7 @@
 using System.Collections.Generic;
 
 using Mono.Unix;
+
 using Hyena;
 using Hyena.Data;
 using Hyena.Data.Sqlite;
@@ -44,6 +45,12 @@
 
 namespace Banshee.Collection.Database
 {
+    public enum ReloadTrigger {
+        Query,
+        ArtistFilter,
+        AlbumFilter
+    };
+        
     public class TrackListDatabaseModel : TrackListModel, IExportableModel, 
         ICacheableDatabaseModel, IFilterable, ISortable, ICareAboutView
     {
@@ -51,8 +58,6 @@
         private readonly BansheeModelProvider<DatabaseTrackInfo> provider;
         private BansheeModelCache<DatabaseTrackInfo> cache;
         private long count;
-        private TimeSpan duration;
-        private long filesize;
 
         private long filtered_count;
         private TimeSpan filtered_duration;
@@ -65,7 +70,7 @@
         private string reload_fragment;
         private string join_table, join_fragment, join_primary_key, join_column, condition;
 
-        private string filter_query;
+        private string query_fragment;
         private string filter;
         private string artist_id_filter_query;
         private string album_id_filter_query;
@@ -107,13 +112,13 @@
                 return;
 
             if (String.IsNullOrEmpty (Filter)) {
-                filter_query = null;
+                query_fragment = null;
             } else {
                 QueryNode query_tree = UserQueryParser.Parse (Filter, BansheeQuery.FieldSet);
-                filter_query = (query_tree == null) ? null : query_tree.ToSql (BansheeQuery.FieldSet);
+                query_fragment = (query_tree == null) ? null : query_tree.ToSql (BansheeQuery.FieldSet);
 
-                if (filter_query != null && filter_query.Length == 0) {
-                    filter_query = null;
+                if (query_fragment != null && query_fragment.Length == 0) {
+                    query_fragment = null;
                 }
             }
 
@@ -127,14 +132,6 @@
                 : BansheeQuery.GetSort (sort_column.SortKey, sort_column.SortType == SortType.Ascending);
         }
 
-        public void Refilter ()
-        {
-            lock (this) {
-                GenerateFilterQueryPart ();
-                cache.Clear ();
-            }
-        }
-        
         public void Sort (ISortableColumn column)
         {
             lock (this) {
@@ -187,15 +184,10 @@
 
         private void UpdateUnfilteredAggregates ()
         {
-            using (IDataReader reader = connection.Query (String.Format (
-                "SELECT COUNT(*), {0} {1}", SelectAggregates, UnfilteredQuery)))
-            {
-                if (reader.Read ()) {
-                    count = Convert.ToInt32 (reader[0]);
-                    duration = TimeSpan.FromMilliseconds (reader.IsDBNull (1) ? 0 : Convert.ToInt64 (reader[1]));
-                    filesize = reader.IsDBNull (2) ? 0 : Convert.ToInt64 (reader[2]);
-                }
-            }
+            HyenaSqliteCommand count_command = new HyenaSqliteCommand (String.Format (
+                "SELECT COUNT(*) {0}", UnfilteredQuery
+            ));
+            count = connection.Query<long> (count_command);
         }
 
         /*private void UpdateFilteredAggregates ()
@@ -204,45 +196,85 @@
             filtered_count = cache.Count;
         }*/
         
-        private bool first_reload = true;
         public override void Reload ()
         {
-            Reload (false, true);
+            Reload (ReloadTrigger.Query);
         }
 
-        public void Reload (bool unfiltered, bool notify)
+        public void Reload (ReloadTrigger trigger)
         {
-            Refilter ();
+            GenerateFilterQueryPart ();
 
             UpdateUnfilteredAggregates ();
+            cache.SaveSelection ();
 
-            StringBuilder qb = new StringBuilder ();
-            qb.Append (UnfilteredQuery);
+            if (trigger == ReloadTrigger.AlbumFilter) {
+                ReloadWithFilters ();
+            } else {
+                ReloadWithoutArtistAlbumFilters ();
+
+                if (trigger == ReloadTrigger.Query) {
+                    artist_model.Reload ();
+                }
 
-            ArtistListDatabaseModel artist_model = unfiltered ? null : this.artist_model;
-            AlbumListDatabaseModel album_model = unfiltered ? null : this.album_model;
+                album_model.Reload ();
 
-            if (artist_model != null) {
-                ArtistInfoFilter = artist_model.SelectedItems;
+                // Unless both artist/album selections are "all" (eg unfiltered), reload
+                // the track model again with the artist/album filters now in place.
+                if (!artist_model.Selection.AllSelected || !album_model.Selection.AllSelected) {
+                    ReloadWithFilters ();
+                }
             }
 
-            if (album_model != null) {
-                AlbumInfoFilter = album_model.SelectedItems;
+            cache.UpdateAggregates ();
+            cache.RestoreSelection ();
+
+            filtered_count = cache.Count;
+
+            OnReloaded ();
+        }
+
+        private void ReloadWithoutArtistAlbumFilters ()
+        {
+            StringBuilder qb = new StringBuilder ();
+            qb.Append (UnfilteredQuery);
+
+            if (query_fragment != null) {
+                qb.Append ("AND ");
+                qb.Append (query_fragment);
             }
             
-            if (!unfiltered && artist_id_filter_query != null) {
+            if (sort_query != null) {
+                qb.Append (" ORDER BY ");
+                qb.Append (sort_query);
+            }
+                
+            reload_fragment = qb.ToString ();
+
+            cache.Reload ();
+        }
+
+        private void ReloadWithFilters ()
+        {
+            StringBuilder qb = new StringBuilder ();
+            qb.Append (UnfilteredQuery);
+
+            ArtistInfoFilter = artist_model.SelectedItems;
+            AlbumInfoFilter = album_model.SelectedItems;
+
+            if (artist_id_filter_query != null) {
                 qb.Append ("AND ");
                 qb.Append (artist_id_filter_query);
             }
                     
-            if (!unfiltered && album_id_filter_query != null) {
+            if (album_id_filter_query != null) {
                 qb.Append ("AND ");
                 qb.Append (album_id_filter_query);
             }
             
-            if (filter_query != null) {
+            if (query_fragment != null) {
                 qb.Append ("AND ");
-                qb.Append (filter_query);
+                qb.Append (query_fragment);
             }
             
             if (sort_query != null) {
@@ -252,21 +284,7 @@
                 
             reload_fragment = qb.ToString ();
 
-            if (!first_reload || !cache.Warm) {
-                cache.Reload ();
-            }
-
-            filtered_count = cache.Count;
-            first_reload = false;
-
-            if (notify) {
-                OnReloaded ();
-            }
-        }
-
-        internal void NotifyReloaded ()
-        {
-            OnReloaded ();
+            cache.Reload ();
         }
 
         public override int IndexOf (TrackInfo track)
@@ -284,25 +302,17 @@
         }
 
         public TimeSpan Duration {
-            get { return duration; }
+            get { return filtered_duration; }
         }
 
         public long FileSize {
-            get { return filesize; }
+            get { return filtered_filesize; }
         }
         
         public int UnfilteredCount {
             get { return (int) count; }
         }
 
-        public TimeSpan FilteredDuration {
-            get { return filtered_duration; }
-        }
-
-        public long FilteredFileSize {
-            get { return filtered_filesize; }
-        }
-        
         public string Filter {
             get { return filter; }
             set { 

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/SelectAllSelection.cs	Tue Mar 11 23:44:39 2008
@@ -55,7 +55,7 @@
         }
 
         public override bool AllSelected {
-            get { return Contains (0); }
+            get { return Contains (0) || (Count == 2 && Contains (1)); }
         }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs	Tue Mar 11 23:44:39 2008
@@ -307,10 +307,16 @@
                 )
             ");
             Execute("CREATE INDEX CoreTracksSourceIndex ON CoreTracks(SourceID)");
+            Execute("CREATE INDEX CoreTracksAggregatesIndex ON CoreTracks(FileSize, Duration)");
             Execute("CREATE INDEX CoreTracksArtistIndex ON CoreTracks(ArtistID)");
             Execute("CREATE INDEX CoreTracksAlbumIndex  ON CoreTracks(AlbumID)");
             Execute("CREATE INDEX CoreTracksRatingIndex ON CoreTracks(Rating)");
-            Execute("CREATE INDEX CoreTracksTrackNumberIndex ON CoreTracks(AlbumID, TrackNumber)");
+            Execute("CREATE INDEX CoreTracksLastPlayedStampIndex ON CoreTracks(LastPlayedStamp)");
+            Execute("CREATE INDEX CoreTracksDateAddedStampIndex ON CoreTracks(DateAddedStamp)");
+            Execute("CREATE INDEX CoreTracksPlayCountIndex ON CoreTracks(PlayCount)");
+            Execute("CREATE INDEX CoreTracksDiscIndex ON CoreTracks(Disc)");
+            Execute("CREATE INDEX CoreTracksTrackNumberIndex ON CoreTracks(TrackNumber)");
+            Execute("CREATE INDEX CoreTracksTitleeIndex ON CoreTracks(Title)");
             
             Execute(@"
                 CREATE TABLE CoreAlbums (
@@ -361,7 +367,8 @@
                     ViewOrder           INTEGER NOT NULL DEFAULT 0
                 )
             ");
-            Execute("CREATE INDEX CorePlaylistEntriesIndex ON CorePlaylistEntries(PlaylistID, EntryID)");
+            Execute("CREATE INDEX CorePlaylistEntriesIndex ON CorePlaylistEntries(PlaylistID)");
+            Execute("CREATE INDEX CorePlaylistTrackIDIndex ON CorePlaylistEntries(TrackID)");
             
             Execute(@"
                 CREATE TABLE CoreSmartPlaylists (
@@ -381,8 +388,8 @@
                     TrackID             INTEGER NOT NULL
                 )
             ");
-            Execute("CREATE INDEX CoreSmartPlaylistEntriesPlaylistIndex ON CoreSmartPlaylistEntries(EntryID, SmartPlaylistID)");
-            Execute("CREATE INDEX CoreSmartPlaylistEntriesTrackIndex ON CoreSmartPlaylistEntries(SmartPlaylistID, TrackID)");
+            Execute("CREATE INDEX CoreSmartPlaylistEntriesPlaylistIndex ON CoreSmartPlaylistEntries(SmartPlaylistID)");
+            Execute("CREATE INDEX CoreSmartPlaylistEntriesTrackIndex ON CoreSmartPlaylistEntries(TrackID)");
 
             Execute(@"
                 CREATE TABLE CoreRemovedTracks (

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Query/BansheeQuery.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Query/BansheeQuery.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Query/BansheeQuery.cs	Tue Mar 11 23:44:39 2008
@@ -201,7 +201,7 @@
             DateAddedField, PlaylistField, SmartPlaylistField
         );
 
-        private const string default_sort = "lower(CoreArtists.Name) ASC, lower(CoreAlbums.Title) ASC, CoreTracks.Disc ASC, CoreTracks.TrackNumber ASC, CoreTracks.Uri ASC";
+        private const string default_sort = "CoreArtists.Name ASC, CoreAlbums.Title ASC, CoreTracks.Disc ASC, CoreTracks.TrackNumber ASC, CoreTracks.Uri ASC";
 
         public static string GetSort (string key)
         {
@@ -215,15 +215,15 @@
             switch(key) {
                 case "Track":
                     sort_query = String.Format (@"
-                        lower(CoreArtists.Name) ASC, 
-                        lower(CoreAlbums.Title) ASC, 
+                        CoreArtists.Name ASC, 
+                        CoreAlbums.Title ASC, 
                         CoreTracks.TrackNumber {0}", ascDesc); 
                     break;
 
                 case "Artist":
                     sort_query = String.Format (@"
-                        lower(CoreArtists.Name) {0}, 
-                        lower(CoreAlbums.Title) ASC,
+                        CoreArtists.Name {0}, 
+                        CoreAlbums.Title ASC,
                         CoreTracks.Disc ASC,
                         CoreTracks.TrackNumber ASC,
                         CoreTracks.Uri ASC", ascDesc); 
@@ -231,7 +231,7 @@
 
                 case "Album":
                     sort_query = String.Format (@"
-                        lower(CoreAlbums.Title) {0},
+                        CoreAlbums.Title {0},
                         CoreTracks.Disc ASC,
                         CoreTracks.TrackNumber ASC,
                         CoreTracks.Uri ASC", ascDesc); 
@@ -239,9 +239,9 @@
 
                 case "Title":
                     sort_query = String.Format (@"
-                        lower(CoreTracks.Title) {0},
-                        lower(CoreArtists.Name) ASC, 
-                        lower(CoreAlbums.Title) ASC", ascDesc); 
+                        CoreTracks.Title {0},
+                        CoreArtists.Name ASC, 
+                        CoreAlbums.Title ASC", ascDesc); 
                     break;
 
                 case "Random":

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs	Tue Mar 11 23:44:39 2008
@@ -291,24 +291,24 @@
 
 #region DatabaseSource overrides
 
-        protected override void ReloadTrackModel (bool unfiltered, bool notify)
+        public void RefreshAndReload ()
         {
-            // The first time ReloadTrackModel is called, it is called with unfiltered = true,
-            // so only repopulate the smart playlist entries then.
-            if (unfiltered) {
-                // Wipe the member list clean and repopulate it 
-                ServiceManager.DbConnection.Execute (String.Format (
-                    @"DELETE FROM CoreSmartPlaylistEntries WHERE SmartPlaylistID = {0};
-                      INSERT INTO CoreSmartPlaylistEntries 
-                        SELECT NULL, {0} as SmartPlaylistID, TrackId
-                            FROM CoreTracks, CoreArtists, CoreAlbums
-                            WHERE CoreTracks.ArtistID = CoreArtists.ArtistID AND CoreTracks.AlbumID = CoreAlbums.AlbumID
-                            {1} {2}",
-                    DbId, PrependCondition("AND"), OrderAndLimit
-                ));
-            }
+            Refresh ();
+            Reload ();
+        }
 
-            base.ReloadTrackModel (unfiltered, notify);
+        public void Refresh ()
+        {
+            // Wipe the member list clean and repopulate it 
+            ServiceManager.DbConnection.Execute (String.Format (
+                @"DELETE FROM CoreSmartPlaylistEntries WHERE SmartPlaylistID = {0};
+                  INSERT INTO CoreSmartPlaylistEntries 
+                    SELECT NULL, {0} as SmartPlaylistID, TrackId
+                        FROM CoreTracks, CoreArtists, CoreAlbums
+                        WHERE CoreTracks.ArtistID = CoreArtists.ArtistID AND CoreTracks.AlbumID = CoreAlbums.AlbumID
+                        {1} {2}",
+                DbId, PrependCondition("AND"), OrderAndLimit
+            ));
         }
 
 #endregion
@@ -347,7 +347,7 @@
         {
             if (args.When > last_added) {
                 last_added = args.When;
-                Reload ();
+                RefreshAndReload ();
             }
         }
 
@@ -355,7 +355,7 @@
         {
             if (args.When > last_updated) {
                 last_updated = args.When;
-                Reload ();
+                RefreshAndReload ();
             }
         }
 
@@ -363,6 +363,7 @@
         {
             if (args.When > last_removed) {
                 last_removed = args.When;
+                RefreshAndReload ();
                 Reload ();
                 /*if (ServiceManager.DbConnection.Query<int> (count_removed_command, last_removed) > 0) {
                     if (Limit == null) {

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs	Tue Mar 11 23:44:39 2008
@@ -31,6 +31,8 @@
 using System.Collections.Generic;
 
 using Mono.Unix;
+
+using Hyena;
 using Hyena.Data;
 using Hyena.Query;
 using Hyena.Data.Sqlite;
@@ -78,18 +80,10 @@
             get { return track_model.Duration; }
         }
 
-        public TimeSpan FilteredDuration {
-            get { return track_model.FilteredDuration; }
-        }
-
         public long FileSize {
             get { return track_model.FileSize; }
         }
 
-        public long FilteredFileSize {
-            get { return track_model.FilteredFileSize; }
-        }
-
         public override string FilterQuery {
             set {
                 base.FilterQuery = value;
@@ -144,36 +138,11 @@
         protected void RateLimitedReload ()
         {
             lock (track_model) {
-                // First, reload the track model w/o the artist/album filter
-                ReloadTrackModel (true, false);
-
-                // Then, reload the artist/album models
-                artist_model.Reload ();
-                album_model.Reload ();
-
-                // Then, reload the track model with the artist/album filters, if any
-                if (!artist_model.Selection.AllSelected || !album_model.Selection.AllSelected) {
-                    ReloadTrackModel ();
-                } else {
-                    track_model.NotifyReloaded ();
-                }
-
+                track_model.Reload ();
                 OnUpdated ();
             }
         }
 
-        protected void ReloadTrackModel ()
-        {
-            ReloadTrackModel (false, true);
-        }
-
-        protected virtual void ReloadTrackModel (bool unfiltered, bool notify)
-        {
-            track_model.Reload (unfiltered, notify);
-            //Hyena.Log.DebugFormat ("Called {0}::ReloadTrackModel ({1}) [Count={2}]", GetType ().FullName, 
-            //    notify, track_model.Count);
-        }
-
         public virtual bool HasDependencies {
             get { return false; }
         }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/IDurationAggregator.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/IDurationAggregator.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/IDurationAggregator.cs	Tue Mar 11 23:44:39 2008
@@ -33,6 +33,5 @@
     public interface IDurationAggregator
     {
         TimeSpan Duration { get; }
-        TimeSpan FilteredDuration { get; }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/IFileSizeAggregator.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/IFileSizeAggregator.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/IFileSizeAggregator.cs	Tue Mar 11 23:44:39 2008
@@ -31,6 +31,5 @@
     public interface IFileSizeAggregator
     {
         long FileSize { get; }
-        long FilteredFileSize { get; }
     }
 }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs	Tue Mar 11 23:44:39 2008
@@ -342,7 +342,7 @@
             if (this is IDurationAggregator) {
                 builder.Append (", ");
 
-                TimeSpan span = (this as IDurationAggregator).FilteredDuration; 
+                TimeSpan span = (this as IDurationAggregator).Duration; 
                 if (span.Days > 0) {
                     double days = span.Days + (span.Hours / 24.0);
                     builder.AppendFormat (Catalog.GetPluralString ("{0} day", "{0:0.0} days", 
@@ -359,7 +359,7 @@
             }
 
             if (this is IFileSizeAggregator) {
-                long bytes = (this as IFileSizeAggregator).FilteredFileSize;
+                long bytes = (this as IFileSizeAggregator).FileSize;
                 if (bytes > 0) {
                     builder.Append (", ");
                     builder.AppendFormat (new FileSizeQueryValue (bytes).ToUserQuery ());

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/TrackListView.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/TrackListView.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Collection.Gui/TrackListView.cs	Tue Mar 11 23:44:39 2008
@@ -52,11 +52,13 @@
         {
             column_controller = new PersistentColumnController ("track_view_columns");
 
+            SortableColumn artist_column = new SortableColumn (Catalog.GetString ("Artist"), new ColumnCellText ("ArtistName", true), 0.225, "Artist");
+
             column_controller.AddRange (
                 new Column (null, "indicator", new ColumnCellPlaybackIndicator (null), 0.05),
                 new SortableColumn (Catalog.GetString ("Track"), new ColumnCellTrackNumber ("TrackNumber", true), 0.10, "Track"),
                 new SortableColumn (Catalog.GetString ("Title"), new ColumnCellText ("TrackTitle", true), 0.25, "Title"),
-                new SortableColumn (Catalog.GetString ("Artist"), new ColumnCellText ("ArtistName", true), 0.225, "Artist"),
+                artist_column,
                 new SortableColumn (Catalog.GetString ("Album"), new ColumnCellText ("AlbumTitle", true), 0.225, "Album"),
                 new SortableColumn (Catalog.GetString ("Duration"), new ColumnCellDuration ("Duration", true), 0.15, "Duration"),
                 
@@ -73,7 +75,7 @@
             column_controller.Load ();
             
             ColumnController = DefaultColumnController;
-            ColumnController.DefaultSortColumn = ColumnController[3] as SortableColumn;
+            ColumnController.DefaultSortColumn = artist_column;
 
             RulesHint = true;
             RowSensitivePropertyName = "CanPlay";

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.SmartPlaylist.Gui/Editor.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.SmartPlaylist.Gui/Editor.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.SmartPlaylist.Gui/Editor.cs	Tue Mar 11 23:44:39 2008
@@ -233,6 +233,7 @@
                         playlist.LimitValue = limit_value;
 
                         playlist.Save ();
+                        playlist.Refresh ();
                         ThreadAssist.ProxyToMain (delegate {
                             ServiceManager.SourceManager.DefaultSource.AddChildSource (playlist);
                         });
@@ -245,7 +246,7 @@
 
                         playlist.Rename (name);
                         playlist.Save ();
-                        playlist.Reload ();
+                        playlist.RefreshAndReload ();
 
                         /*if (playlist.TimeDependent)
                             SmartPlaylistCore.Instance.StartTimer (playlist);

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Sources.Gui/CompositeTrackSourceContents.cs	Tue Mar 11 23:44:39 2008
@@ -267,20 +267,12 @@
 
             if (selection.AllSelected) {
                 if (model != null && o == artist_view.Selection ) {
-                    track_source.Reload ();
                     artist_view.ScrollTo (0);
                 } else if (model != null && o == album_view.Selection) {
-                    track_source.Reload ();
                     album_view.ScrollTo (0);
                 }
                 return;
             }
-            
-            if (o == artist_view.Selection) {
-                track_source.Reload ();
-            } else if (o == album_view.Selection) {
-                track_source.Reload ();
-            }
         }
 
         public void SetModels (TrackListModel track, ArtistListModel artist, AlbumListModel album)

Modified: trunk/banshee/src/Extensions/Banshee.Lastfm/Resources/tag.png
==============================================================================
Binary files. No diff available.

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs	Tue Mar 11 23:44:39 2008
@@ -50,7 +50,6 @@
         private long selection_uid;
         private long rows;
         // private bool warm;
-        private bool first_reload = true;
         private long first_order_id;
 
         public delegate void AggregatesUpdatedEventHandler (IDataReader reader);
@@ -129,7 +128,7 @@
 
                 reload_sql = String.Format (@"
                     DELETE FROM {0} WHERE ModelID = {1};
-                        INSERT INTO {0} SELECT null, {1}, {2} ",
+                        INSERT INTO {0} (ModelID, ItemID) SELECT {1}, {2} ",
                     CacheTableName, uid, model.JoinPrimaryKey
                 );
             } else {
@@ -161,7 +160,7 @@
 
                 reload_sql = String.Format (@"
                     DELETE FROM {0} WHERE ModelID = {1};
-                        INSERT INTO {0} SELECT null, {1}, {2} ",
+                        INSERT INTO {0} (ModelID, ItemID) SELECT {1}, {2} ",
                     CacheTableName, uid, provider.PrimaryKey
                 );
             }
@@ -178,7 +177,7 @@
             ));
             
             save_selection_command = new HyenaSqliteCommand (String.Format (
-                "INSERT INTO {0} SELECT null, {1}, ItemID FROM {0} WHERE ModelID = {2} LIMIT ?, ?",
+                "INSERT INTO {0} (ModelID, ItemID) SELECT {1}, ItemID FROM {0} WHERE ModelID = {2} LIMIT ?, ?",
                 CacheTableName, selection_uid, uid
             ));
 
@@ -243,7 +242,7 @@
         private HyenaSqliteCommand last_reload_command;
         private string last_reload_fragment;
 
-        public override long Reload ()
+        public override void Reload ()
         {
             lock (this) {
                 if (last_reload_fragment != model.ReloadFragment) {
@@ -251,30 +250,15 @@
                     last_reload_command = new HyenaSqliteCommand (reload_sql + last_reload_fragment);
                 }
 
-                if (!first_reload) {
-                    SaveSelection ();
-                }
-
                 Clear ();
-
-                //using (new Timer (String.Format ("Generating cache table for {0}", model))) {
-                    connection.Execute (last_reload_command);
-                //}
+                //Log.DebugFormat ("Reloading {0} with {1}", model, last_reload_command.Text);
+                connection.Execute (last_reload_command);
                 first_order_id = -1;
-                UpdateAggregates ();
-
-                if (!first_reload) {
-                    RestoreSelection ();
-                } else {
-                    first_reload = false;
-                }
-
-                return rows;
             }
         }
 
         private bool saved_selection = false;
-        private void SaveSelection ()
+        public void SaveSelection ()
         {
             if (model.Selection.Count > 0 && !(has_select_all_item && model.Selection.AllSelected)) {
                 connection.Execute (delete_selection_command);
@@ -298,7 +282,7 @@
             }
         }
 
-        private void RestoreSelection ()
+        public void RestoreSelection ()
         {
             long selected_id = -1;
             long first_id = FirstOrderId;
@@ -322,12 +306,12 @@
             if (has_select_all_item && model.Selection.Count == 0) {
                 model.Selection.QuietSelect (0);
             }
+            saved_selection = false;
         }
 
         protected override void FetchSet (long offset, long limit)
         {
             lock (this) {
-            //using (new Timer (String.Format ("Fetching set for {0}", model))) {
                 using (IDataReader reader = connection.Query (select_range_command, offset, limit)) {
                     T item;
                     while (reader.Read ()) {
@@ -337,13 +321,12 @@
                             Add (offset, item);
                         }
                         offset++;
-                     }
-                 }
-            //}
+                    }
+                }
             }
         }
         
-        protected void UpdateAggregates ()
+        public void UpdateAggregates ()
         {
             using (IDataReader reader = connection.Query (count_command, uid)) {
                 if (reader.Read ()) {

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data/IFilterable.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data/IFilterable.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data/IFilterable.cs	Tue Mar 11 23:44:39 2008
@@ -30,7 +30,6 @@
 {
     public interface IFilterable
     {
-        void Refilter ();
         string Filter { get; set; }
         int UnfilteredCount { get; }
     }

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data/ModelCache.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data/ModelCache.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data/ModelCache.cs	Tue Mar 11 23:44:39 2008
@@ -58,8 +58,8 @@
         // Responsible for fetching a set of items and placing them in the cache
         protected abstract void FetchSet (long offset, long limit);
 
-        // Reset the cache and return the total # of items in the model
-        public abstract long Reload ();
+        // Regenerate the cache
+        public abstract void Reload ();
 
         public abstract bool ContainsKey (long i);
         public abstract void Add (long i, T item);



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