[banshee] Banshee.Services: Avoid creating dupes after moves (bgo#638889)



commit e9de1807a255ca4ba51cda6a4f23d314b38d4450
Author: Andrés G. Aragoneses <knocte gmail com>
Date:   Wed May 11 00:03:56 2011 +0200

    Banshee.Services: Avoid creating dupes after moves (bgo#638889)
    
    When importing, besides checking that there is not already
    an entry with the same Uri, now we check also for the same
    MetadataHash. If there is an entry which points to an URI
    that doesn't exist anymore and have the same hash for a file
    to be imported, we consider it outdated, and we update its
    URI with the one of the file that was going to be imported,
    so we avoid a broken duplicate and we keep the same
    DateAdded value that we had originally.

 .../DatabaseImportManager.cs                       |   38 +++++++++++++++-----
 .../DatabaseTrackInfo.cs                           |   32 ++++++++++++++++
 2 files changed, 61 insertions(+), 9 deletions(-)
---
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs
index 82a8a0e..39f48a0 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs
@@ -168,20 +168,23 @@ namespace Banshee.Collection.Database
                 return null;
             }
 
-            DatabaseTrackInfo track = null;
+            DatabaseTrackInfo track = new DatabaseTrackInfo () { Uri = uri };
+            using (var file = StreamTagger.ProcessUri (uri)) {
+                StreamTagger.TrackInfoMerge (track, file, false, true);
+            }
+
+            track.Uri = uri;
+
+            if (FindOutdatedDupe (track)) {
+                return null;
+            }
+
+            track.PrimarySource = trackPrimarySourceChooser (track);
 
             // TODO note, there is deadlock potential here b/c of locking of shared commands and blocking
             // because of transactions.  Needs to be fixed in HyenaDatabaseConnection.
             ServiceManager.DbConnection.BeginTransaction ();
             try {
-                track = new DatabaseTrackInfo () { Uri = uri };
-                using (var file = StreamTagger.ProcessUri (uri)) {
-                    StreamTagger.TrackInfoMerge (track, file, false, true);
-                }
-
-                track.Uri = uri;
-                track.PrimarySource = trackPrimarySourceChooser (track);
-
                 bool save_track = true;
                 if (track.PrimarySource is Banshee.Library.LibrarySource) {
                     save_track = track.CopyToLibraryIfAppropriate (force_copy);
@@ -208,6 +211,23 @@ namespace Banshee.Collection.Database
             return track;
         }
 
+        private bool FindOutdatedDupe (DatabaseTrackInfo track)
+        {
+            if (DatabaseTrackInfo.MetadataHashCount (track.MetadataHash, PrimarySourceIds) != 1) {
+                return false;
+            }
+
+            var track_to_update = DatabaseTrackInfo.GetTrackForMetadataHash (track.MetadataHash, PrimarySourceIds);
+
+            if (track_to_update == null || Banshee.IO.File.Exists (track_to_update.Uri)) {
+                return false;
+            }
+
+            track_to_update.Uri = track.Uri;
+            track_to_update.Save ();
+            return true;
+        }
+
         private void LogError (string path, Exception e)
         {
             LogError (path, e.Message);
diff --git a/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs
index 6cc0d62..37686a9 100644
--- a/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs
+++ b/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs
@@ -776,6 +776,13 @@ namespace Banshee.Collection.Database
             "SELECT TrackID FROM CoreTracks WHERE PrimarySourceId IN (?) AND Uri = ? LIMIT 1"
         );
 
+        private static string get_track_by_metadata_hash =
+            "SELECT {0} FROM {1} WHERE {2} AND PrimarySourceId IN (?) AND MetadataHash = ? LIMIT 1";
+
+        private static HyenaSqliteCommand get_track_count_by_metadata_hash = new HyenaSqliteCommand (
+            "SELECT COUNT('x') FROM CoreTracks WHERE PrimarySourceId IN (?) AND MetadataHash = ?"
+        );
+
         public static int GetTrackIdForUri (SafeUri uri, int [] primary_sources)
         {
             return ServiceManager.DbConnection.Query<int> (get_track_id_by_uri,
@@ -788,11 +795,36 @@ namespace Banshee.Collection.Database
                 primary_sources, absoluteUri);
         }
 
+        private static IDataReader FindTrackByMetadataHash (string metadata_hash, int [] primary_sources)
+        {
+            var command = new HyenaSqliteCommand (String.Format (
+                get_track_by_metadata_hash,
+                provider.Select, provider.From, provider.Where));
+            return ServiceManager.DbConnection.Query (command,
+                primary_sources, metadata_hash);
+        }
+
         public static bool ContainsUri (SafeUri uri, int [] primary_sources)
         {
             return GetTrackIdForUri (uri, primary_sources) > 0;
         }
 
+        internal static DatabaseTrackInfo GetTrackForMetadataHash (string metadata_hash, int [] primary_sources)
+        {
+            using (IDataReader reader = FindTrackByMetadataHash (metadata_hash, primary_sources)) {
+                if (reader.Read ()) {
+                    return provider.Load (reader);
+                }
+                return null;
+            }
+        }
+
+        internal static int MetadataHashCount (string metadata_hash, int [] primary_sources)
+        {
+            return ServiceManager.DbConnection.Query<int> (get_track_count_by_metadata_hash,
+                primary_sources, metadata_hash);
+        }
+
         public static void UpdateMetadataHash (string albumTitle, string artistName, string condition)
         {
             // Keep this field set/order in sync with MetadataHash in TrackInfo.cs



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