banshee r3353 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Base src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Database src/Core/Banshee.Services/Banshee.Library src/Core/Banshee.Services/Banshee.SmartPlaylist src/Core/Banshee.Services/Banshee.Sources src/Core/Banshee.ThickClient/Banshee.Gui src/Libraries/Hyena/Hyena.Data.Sqlite



Author: gburt
Date: Fri Feb 29 00:50:35 2008
New Revision: 3353
URL: http://svn.gnome.org/viewvc/banshee?rev=3353&view=rev

Log:
2008-02-28  Gabriel Burt  <gabriel burt gmail com>

	* src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs:
	Add a Save (bool notify) method so processes that are triggering lots of
	Save's can avoid notifying the track's PrimarySource until they choose to
	- eg in the metadata refresh process.

	* src/Core/Banshee.Services/Banshee.Database/BansheeDbConnection.cs:
	Add comment to PRAGMA cache_size call.

	* src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs:
	Add indices to Core[Smart]PlaylistEntries, and use track.Save (false) when
	updating the metadata.

	* src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs: Set
	Library.Importing = true/false around the import process.

	* src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs: Add
	ReloadChildren method.  Add RateSelectedTracks method.

	* src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs: Add
	Importing property that when set true increases the period between
	TrackUpdated calls to 5 s (from the normal 0.25 s).  Fix bug where Reload
	always reloaded all children - not something we want to do when the user
	is searching, say.  Explicitly call ReloadChildren where needed.

	* src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs: Make more thread
	safe.

	* src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs: Add an
	ActiveSource convenience property.

	* src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs: Use
	ActiveSource property.

	* src/Core/Banshee.ThickClient/Banshee.Gui/TrackActions.cs: Use new
	ActiveSource property, and call RateSelectedTracks to rate entire
	selection Ranges at a time - much much faster.

	* src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteCommand.cs: Make
	Execute and WaitForResult internal methods.

	* src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs: Put
	locks on the current command around Query/Execute calls to prevent a
	thread from calling the same command before an earlier thread gets its
	result.

	* src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs: Avoid
	checking the cache table more times than necessary.


Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Base/ThreadAssist.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbConnection.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.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/PrimarySource.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs
   trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/TrackActions.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteCommand.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Base/RateLimiter.cs	Fri Feb 29 00:50:35 2008
@@ -41,6 +41,12 @@
         private DateTime last_executed = DateTime.MinValue;
         private uint timeout_id = 0;
 
+        private bool requested = false;
+        private double requested_interval;
+        private bool executing = false;
+
+        private string name;
+
         public RateLimiter (double min_interval_ms, RateLimitedMethod method) : this (0.0, min_interval_ms, method)
         {
         }
@@ -59,28 +65,47 @@
 
         public void Execute (double min_interval_ms)
         {
-            if (timeout_id != 0)
-                return;
+            lock (this) {
+                if (requested || timeout_id != 0) {
+                    return;
+                }
 
-            double delta = (DateTime.Now - last_executed).TotalMilliseconds;
-            if (delta >= min_interval_ms) {
-                if (initial_delay_ms == 0.0) {
-                    method ();
-                    last_executed = DateTime.Now;
-                } else {
+                if (executing) {
+                    requested = true;
+                    requested_interval = min_interval_ms;
+                    return;
+                }
+
+                double delta = (DateTime.Now - last_executed).TotalMilliseconds;
+                if (delta >= min_interval_ms) {
                     timeout_id = GLib.Timeout.Add ((uint) initial_delay_ms, OnRateLimitTimer);
+                } else {
+                    timeout_id = GLib.Timeout.Add ((uint) (min_interval_ms - delta), OnRateLimitTimer);
                 }
-            } else {
-                //Console.WriteLine ("Method rate limited, setting timeout");
-                timeout_id = GLib.Timeout.Add ((uint) min_interval_ms, OnRateLimitTimer);
             }
         }
 
         private bool OnRateLimitTimer ()
         {
-            timeout_id = 0;
+            lock (this) {
+                timeout_id = 0;
+                executing = true;
+            }
+
+            //Hyena.Log.DebugFormat ("Executing method {0} from {1} in {2}", method.Method.Name, method.Method.DeclaringType, System.Threading.Thread.CurrentThread.ManagedThreadId);
             method ();
-            last_executed = DateTime.Now;
+
+            lock (this) {
+                last_executed = DateTime.Now;
+                //Hyena.Log.DebugFormat ("Done executing method {0} from {1} at {2}", method.Method.Name, method.Method.DeclaringType, last_executed);
+                executing = false;
+            }
+
+            if (requested) {
+                requested = false;
+                Execute (requested_interval);
+            }
+
             return false;
         }
     }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Base/ThreadAssist.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Base/ThreadAssist.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Base/ThreadAssist.cs	Fri Feb 29 00:50:35 2008
@@ -58,6 +58,15 @@
                 handler (null, EventArgs.Empty);
             }
         }
+
+        public static void SpawnFromMain (ThreadStart threadedMethod)
+        {
+            if (InMainThread) {
+                Spawn (threadedMethod, true);
+            } else {
+                threadedMethod ();
+            }
+        }
         
         public static Thread Spawn (ThreadStart threadedMethod, bool autoStart)
         {

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs	Fri Feb 29 00:50:35 2008
@@ -71,9 +71,16 @@
 
         public override void Save ()
         {
+            Save (true);
+        }
+
+        public void Save (bool notify)
+        {
             DateUpdated = DateTime.Now;
             Provider.Save (this);
-            Source.OnTracksUpdated ();
+            if (notify) {
+                Source.OnTracksUpdated ();
+            }
         }
         
         [DatabaseColumn ("TrackID", Constraints = DatabaseColumnConstraints.PrimaryKey)]

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbConnection.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbConnection.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbConnection.cs	Fri Feb 29 00:50:35 2008
@@ -46,8 +46,9 @@
 
         public BansheeDbConnection () : base (DatabaseFile)
         {
-            Execute ("PRAGMA synchronous = OFF;");
+            // Each cache page is about 1.5K, so 32768 pages = 49152K = 48M
             Execute ("PRAGMA cache_size = 32768;");
+            Execute ("PRAGMA synchronous = OFF;");
 
             migrator = new BansheeDbFormatMigrator (this);
         }

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	Fri Feb 29 00:50:35 2008
@@ -359,10 +359,11 @@
                 CREATE TABLE CorePlaylistEntries (
                     EntryID             INTEGER PRIMARY KEY,
                     PlaylistID          INTEGER NOT NULL,
-                    TrackID             INTEGER NOT NULL ON CONFLICT IGNORE,
+                    TrackID             INTEGER NOT NULL,
                     ViewOrder           INTEGER NOT NULL DEFAULT 0
                 )
             ");
+            Execute("CREATE INDEX CorePlaylistEntriesIndex ON CorePlaylistEntries(PlaylistID, EntryID)");
             
             Execute(@"
                 CREATE TABLE CoreSmartPlaylists (
@@ -381,6 +382,7 @@
                     TrackID             INTEGER NOT NULL
                 )
             ");
+            Execute("CREATE INDEX CoreSmartPlaylistEntriesIndex ON CoreSmartPlaylistEntries(SmartPlaylistID, TrackID)");
 
             Execute(@"
                 CREATE TABLE CoreCacheModels (
@@ -483,7 +485,7 @@
             if (args.Service is UserJobManager) {
                 ServiceManager.ServiceStarted -= OnServiceStarted;
                 if (ServiceManager.SourceManager.Library != null) {
-                    Application.RunTimeout (3000, RefreshMetadata);
+                    RefreshMetadataDelayed ();
                 } else {
                     ServiceManager.SourceManager.SourceAdded += OnSourceAdded;
                 }
@@ -541,7 +543,7 @@
                         track = DatabaseTrackInfo.Provider.Load (reader, 0);
                         TagLib.File file = StreamTagger.ProcessUri (track.Uri);
                         StreamTagger.TrackInfoMerge (track, file, true);
-                        track.Save ();
+                        track.Save (false);
 
                         job.Status = String.Format ("{0} - {1}", track.DisplayArtistName, track.DisplayTrackTitle);
                     } catch (Exception e) {
@@ -552,6 +554,7 @@
                     job.Progress = (double)++count / (double)total;
                 }
             }
+            ServiceManager.SourceManager.Library.OnTracksUpdated ();
 
             job.Finish ();
         }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs	Fri Feb 29 00:50:35 2008
@@ -94,6 +94,8 @@
                 IncrementProcessedCount (null);
                 return;
             }
+
+            ServiceManager.SourceManager.Library.Importing = true;
             
             try {            
                 DatabaseTrackInfo track = AddTrackToLibrary (path);
@@ -173,6 +175,7 @@
 
         protected override void OnImportFinished ()
         {
+            ServiceManager.SourceManager.Library.Importing = false;
             base.OnImportFinished ();
         }
         

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	Fri Feb 29 00:50:35 2008
@@ -277,7 +277,7 @@
 
 #region DatabaseSource overrides
 
-        protected override void RateLimitedReload ()
+        public override void RateLimitedReload ()
         {
             // Wipe the member list clean
             ServiceManager.DbConnection.Execute (String.Format (

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	Fri Feb 29 00:50:35 2008
@@ -32,6 +32,7 @@
 
 using Mono.Unix;
 using Hyena.Data;
+using Hyena.Data.Sqlite;
 using Hyena.Collections;
 
 using Banshee.Base;
@@ -50,6 +51,8 @@
         protected AlbumListDatabaseModel album_model;
         protected ArtistListDatabaseModel artist_model;
 
+        protected HyenaSqliteCommand rate_track_range_command;
+
         protected RateLimiter reload_limiter;
         
         public DatabaseSource (string generic_name, string name, string id, int order) : base (generic_name, name, order)
@@ -58,6 +61,11 @@
             track_model = new TrackListDatabaseModel (ServiceManager.DbConnection, uuid);
             album_model = new AlbumListDatabaseModel (track_model, ServiceManager.DbConnection, uuid);
             artist_model = new ArtistListDatabaseModel (track_model, ServiceManager.DbConnection, uuid);
+            rate_track_range_command= new HyenaSqliteCommand (String.Format (@"
+                UPDATE CoreTracks SET Rating = ? WHERE TrackID IN (
+                    SELECT ItemID FROM CoreCache WHERE ModelID = {0} LIMIT ?, ?)",
+                track_model.CacheId
+            ));
             reload_limiter = new RateLimiter (50.0, RateLimitedReload);
         }
 
@@ -92,7 +100,7 @@
                 base.FilterQuery = value;
                 track_model.Filter = value;
                 track_model.Refilter ();
-                RateLimitedReload ();
+                Reload ();
             }
         }
 
@@ -134,15 +142,19 @@
 
         public void Reload (double min_interval_ms)
         {
-            reload_limiter.Execute (min_interval_ms);
+            ThreadAssist.SpawnFromMain (delegate {
+                reload_limiter.Execute (min_interval_ms);
+            });
         }
 
         public void Reload ()
         {
-            reload_limiter.Execute (100.0);
+            ThreadAssist.SpawnFromMain (delegate {
+                reload_limiter.Execute (100.0);
+            });
         }
 
-        protected virtual void RateLimitedReload ()
+        public virtual void RateLimitedReload ()
         {
             track_model.Reload ();
             artist_model.Reload ();
@@ -150,6 +162,15 @@
             OnUpdated ();
         }
 
+        protected virtual void ReloadChildren ()
+        {
+            foreach (Source child in Children) {
+                if (child is ITrackModelSource) {
+                    (child as ITrackModelSource).Reload ();
+                }
+            }
+        }
+
         public virtual void RemoveTrack (int index)
         {
             RemoveTrack (track_model [index] as DatabaseTrackInfo);
@@ -192,6 +213,26 @@
             WithTrackSelection (model, DeleteTrackRange);
         }
 
+        public virtual void RateSelectedTracks (int rating)
+        {
+            RateSelectedTracks (track_model, rating);
+        }
+
+        public virtual void RateSelectedTracks (TrackListDatabaseModel model, int rating)
+        {
+            Selection selection = model.Selection;
+            if (selection.Count == 0)
+                return;
+
+            lock (model) {
+                foreach (RangeCollection.Range range in selection.Ranges) {
+                    RateTrackRange (model, range, rating);
+                }
+                Reload ();
+                ReloadChildren ();
+            }
+        }
+
 #endregion
         
 #region Protected Methods
@@ -213,17 +254,24 @@
             throw new NotImplementedException(); 
         }
 
+        protected virtual void RateTrackRange (TrackListDatabaseModel model, RangeCollection.Range range, int rating)
+        {
+            rate_track_range_command.ApplyValues (rating, range.Start, range.End - range.Start + 1);
+            ServiceManager.DbConnection.Execute (rate_track_range_command);
+        }
+
         protected void WithTrackSelection (TrackListDatabaseModel model, TrackRangeHandler handler)
         {
             Selection selection = model.Selection;
             if (selection.Count == 0)
                 return;
 
-            lock (track_model) {
+            lock (model) {
                 foreach (RangeCollection.Range range in selection.Ranges) {
                     handler (model, range);
                 }
                 Reload ();
+                ReloadChildren ();
             }
         }
 

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs	Fri Feb 29 00:50:35 2008
@@ -47,6 +47,7 @@
         protected ErrorSource error_source = new ErrorSource (Catalog.GetString ("Import Errors"));
         protected bool error_source_visible = false;
         protected RateLimiter tracks_updated_limiter;
+        private double tracks_updated_ms = 250.0;
 
         protected HyenaSqliteCommand remove_range_command = new HyenaSqliteCommand (@"
             DELETE FROM CoreTracks WHERE TrackID IN
@@ -94,19 +95,30 @@
             error_source.Updated += OnErrorSourceUpdated;
             OnErrorSourceUpdated (null, null);
 
-            tracks_updated_limiter = new RateLimiter (50.0, 500.0, RateLimitedOnTracksUpdated);
+            tracks_updated_limiter = new RateLimiter (20.0, tracks_updated_ms, RateLimitedOnTracksUpdated);
 
             primary_sources[source_id] = this;
         }
 
+        public bool Importing {
+            set { tracks_updated_ms = value ? 5000.0 : 250.0; }
+        }
+
         public void OnTracksUpdated ()
         {
-            tracks_updated_limiter.Execute ();
+            ThreadAssist.Spawn (delegate {
+                tracks_updated_limiter.Execute (tracks_updated_ms);
+            });
         }
 
         protected virtual void RateLimitedOnTracksUpdated ()
         {
-            Reload ();
+            RateLimitedReload ();
+            foreach (Source child in Children) {
+                if (child is DatabaseSource) {
+                    (child as DatabaseSource).RateLimitedReload ();
+                }
+            }
 
             EventHandler handler = TracksUpdated;
             if (handler != null) {
@@ -114,16 +126,6 @@
             }
         }
 
-        protected override void RateLimitedReload ()
-        {
-            base.RateLimitedReload ();
-            foreach (Source child in Children) {
-                if (child is ITrackModelSource) {
-                    (child as ITrackModelSource).Reload ();
-                }
-            }
-        }
-
         protected void OnErrorSourceUpdated (object o, EventArgs args)
         {
             if (error_source.Count > 0 && !error_source_visible) {
@@ -140,6 +142,7 @@
             remove_track_command.ApplyValues (track.DbId);
             ServiceManager.DbConnection.Execute (remove_track_command);
             Reload ();
+            ReloadChildren ();
         }
 
         /*public override void RemoveTracks (IEnumerable<TrackInfo> tracks)

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/BansheeActionGroup.cs	Fri Feb 29 00:50:35 2008
@@ -88,6 +88,10 @@
             }
         }
 
+        public Source ActiveSource {
+            get { return ServiceManager.SourceManager.ActiveSource; }
+        }
+
         public Gtk.Window PrimaryWindow {
             get { return ServiceManager.Get<GtkElementsService> ("GtkElementsService").PrimaryWindow; }
         }

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/SourceActions.cs	Fri Feb 29 00:50:35 2008
@@ -59,7 +59,7 @@
         }
 
         public Source ActionSource {
-            get { return SourceView.HighlightedSource ?? ServiceManager.SourceManager.ActiveSource; }
+            get { return SourceView.HighlightedSource ?? ActiveSource; }
         }
         
         public SourceActions (InterfaceActionService actionService) : base ("Source")

Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/TrackActions.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/TrackActions.cs	(original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/TrackActions.cs	Fri Feb 29 00:50:35 2008
@@ -321,10 +321,7 @@
             PlaylistSource playlist = new PlaylistSource ("New Playlist");
             playlist.Save ();
             ServiceManager.SourceManager.DefaultSource.AddChildSource (playlist);
-
-            ThreadAssist.Spawn (delegate {
-                playlist.AddSelectedTracks (TrackSelector.TrackModel);
-            });
+            playlist.AddSelectedTracks (TrackSelector.TrackModel);
         }
 
         private void OnAddToExistingPlaylist (object o, EventArgs args)
@@ -334,7 +331,7 @@
 
         private void OnRemoveTracks (object o, EventArgs args)
         {
-            ITrackModelSource source = ServiceManager.SourceManager.ActiveSource as ITrackModelSource;
+            ITrackModelSource source = ActiveSource as ITrackModelSource;
 
             if (!ConfirmRemove (source, false, source.TrackModel.Selection.Count))
                 return;
@@ -346,7 +343,7 @@
 
         private void OnRemoveTracksFromLibrary (object o, EventArgs args)
         {
-            ITrackModelSource source = ServiceManager.SourceManager.ActiveSource as ITrackModelSource;
+            ITrackModelSource source = ActiveSource as ITrackModelSource;
 
             if (source != null) {
                 LibrarySource library = source.Parent as LibrarySource;
@@ -360,7 +357,7 @@
 
         private void OnDeleteTracksFromDrive (object o, EventArgs args)
         {
-            ITrackModelSource source = ServiceManager.SourceManager.ActiveSource as ITrackModelSource;
+            ITrackModelSource source = ActiveSource as ITrackModelSource;
 
             if (!ConfirmRemove (source, true, source.TrackModel.Selection.Count))
                 return;
@@ -380,19 +377,12 @@
                 }
             }
 
-            int rating = rating_proxy.LastRating;
-            foreach (TrackInfo track in TrackSelector.GetSelectedTracks ()) {
-                if (track != null) {
-                    track.Rating = rating;
-                    track.Save ();
-                }
-            }
+            (ActiveSource as DatabaseSource).RateSelectedTracks (rating_proxy.LastRating);
         }
 
         private void OnSearchForSameArtist (object o, EventArgs args)
         {
-            Source source = ServiceManager.SourceManager.ActiveSource;
-            // ITrackModelSource track_source = source as ITrackModelSource; FIXME: What? --Aaron
+            Source source = ActiveSource;
             foreach (TrackInfo track in TrackSelector.GetSelectedTracks ()) {
                 source.FilterQuery = BansheeQuery.ArtistField.ToTermString (":", track.ArtistName);
                 break;
@@ -401,8 +391,7 @@
 
         private void OnSearchForSameAlbum (object o, EventArgs args)
         {
-            Source source = ServiceManager.SourceManager.ActiveSource;
-            // ITrackModelSource track_source = source as ITrackModelSource; FIXME: What? --Aaron
+            Source source = ActiveSource;
             foreach (TrackInfo track in TrackSelector.GetSelectedTracks ()) {
                 source.FilterQuery = BansheeQuery.AlbumField.ToTermString (":", track.AlbumTitle);
                 break;

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteCommand.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteCommand.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteCommand.cs	Fri Feb 29 00:50:35 2008
@@ -59,7 +59,7 @@
         }
 
         private HyenaCommandType command_type;
-        public HyenaCommandType CommandType {
+        internal HyenaCommandType CommandType {
             get { return command_type; }
             set { command_type = value; }
         }
@@ -77,15 +77,18 @@
             ApplyValues (param_values);
         }
 
-        public void Execute (SqliteConnection connection)
+        internal void Execute (SqliteConnection connection)
         {
-            finished = false;
+            if (finished) {
+                throw new Exception ("Command is already set to finished; result needs to be claimed before command can be rerun");
+            }
+
             execution_exception = null;
             result = null;
 
             SqliteCommand sql_command = new SqliteCommand (CurrentSqlText ());
             sql_command.Connection = connection;
-            //Log.Debug ("Executing {0}", sql_command.CommandText);
+            //Log.DebugFormat ("Executing {0}", sql_command.CommandText);
 
             try {
                 switch (command_type) {
@@ -117,18 +120,22 @@
                 conn.ResultReadySignal.WaitOne ();
             }
 
+            object ret = result;
+            
+            // Reset to false in case run again
+            finished = false;
+
             conn.ClaimResult ();
 
             if (execution_exception != null) {
                 throw execution_exception;
             }
             
-            return result;
+            return ret;
         }
 
         public HyenaSqliteCommand ApplyValues (params object [] param_values)
         {
-            finished = false;
             if (command_format == null) {
                 CreateParameters ();
             }

Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs	Fri Feb 29 00:50:35 2008
@@ -78,9 +78,11 @@
         // SELECT multiple column queries
         public IDataReader Query (HyenaSqliteCommand command)
         {
-            command.CommandType = HyenaCommandType.Reader;
-            QueueCommand(command);
-            return command.WaitForResult (this) as SqliteDataReader;
+            lock (command) {
+                command.CommandType = HyenaCommandType.Reader;
+                QueueCommand(command);
+                return command.WaitForResult (this) as SqliteDataReader;
+            }
         }
 
         public IDataReader Query (string command_str, params object [] param_values)
@@ -96,9 +98,12 @@
         // SELECT single column queries
         public T Query<T> (HyenaSqliteCommand command)
         {
-            command.CommandType = HyenaCommandType.Scalar;
-            QueueCommand(command);
-            object result = command.WaitForResult (this);
+            object result = null;
+            lock (command) {
+                command.CommandType = HyenaCommandType.Scalar;
+                QueueCommand(command);
+                result = command.WaitForResult (this);
+            }
 
             return result == null 
                 ? default (T)
@@ -118,9 +123,11 @@
         // INSERT, UPDATE, DELETE queries
         public int Execute (HyenaSqliteCommand command)
         {
-            command.CommandType = HyenaCommandType.Execute;;
-            QueueCommand(command);
-            return (int) command.WaitForResult (this);
+            lock (command) {
+                command.CommandType = HyenaCommandType.Execute;;
+                QueueCommand(command);
+                return (int) command.WaitForResult (this);
+            }
         }
 
         public int Execute (string command_str, params object [] param_values)

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	Fri Feb 29 00:50:35 2008
@@ -215,8 +215,13 @@
             }
         }
 
+        private static string checked_cache_table;
         private void CheckCacheTable ()
         {
+            if (CacheTableName == checked_cache_table) {
+                return;
+            }
+
             if (!connection.TableExists (CacheTableName)) {
                 connection.Execute (String.Format (@"
                     CREATE TABLE {0} (
@@ -232,6 +237,8 @@
                     CacheModelsTableName
                 ));
             }
+
+            checked_cache_table = CacheTableName;
         }
     }
 }



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