banshee r3370 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Database src/Core/Banshee.Services/Banshee.Playlist src/Core/Banshee.Services/Banshee.SmartPlaylist src/Core/Banshee.Services/Banshee.Sources src/Libraries/Hyena/Hyena.Data.Sqlite



Author: gburt
Date: Mon Mar  3 16:37:57 2008
New Revision: 3370
URL: http://svn.gnome.org/viewvc/banshee?rev=3370&view=rev

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

	This patch fixes a poor assumption made quite a while ago that for
	playlists put the TrackID into the CoreCache table, which if you had a
	song in a playlist twice would make it impossible to remove one and not
	the other.

	* src/Core/Banshee.Services/Banshee.Collection.Database/AlbumListDatabaseModel.cs:
	* src/Core/Banshee.Services/Banshee.Collection.Database/ArtistListDatabaseModel.cs:
	Fix reload fragments to use the track_model's JoinTable etc when needed.

	* src/Core/Banshee.Services/Banshee.Collection.Database/TrackListDatabaseModel.cs:
	Add JoinTable, JoinPrimaryKey, and JoinColumn properties that allow the
	model to specify that it joins, for example, the CoreTracks table with the
	CoreCache table via the CorePlaylistEntries table.

	* src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs:
	Add a EntryID primary key to CoreSmartPlaylistEntries, and create an index
	for it.

	* src/Core/Banshee.Services/Banshee.Playlist/AbstractPlaylistSource.cs:
	Add JoinPrimaryKey virtual property, and set the Join* properties.

	* src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs: Fix
	AddTrackRange method to work with track model's that have a join table.

	* src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs:
	Change INSERT to add NULL so primary key automatically set.

	* src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs: Implement
	RemoveTrack by calling RemoveTrackRange with an appropriate Range.  Add
	ReloadPrimarySource method that reloads the current source's "nearest"
	PrimarySource - either itself, its parent, or all PrimarySources.

	* src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs: Remove
	RemoveTrack method - fully implemented in DatabaseSource.

	* src/Libraries/Hyena/Hyena.Data.Sqlite/ICacheableDatabaseModel.cs: Add
	Join properties.

	* src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs: Handle models
	that specify a JoinTable.


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.Database/BansheeDbFormatMigrator.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/AbstractPlaylistSource.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.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/Libraries/Hyena/Hyena.Data.Sqlite/ICacheableDatabaseModel.cs
   trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.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	Mon Mar  3 16:37:57 2008
@@ -75,12 +75,15 @@
                     track_model == null ? null :
                         String.Format (@"
                             CoreAlbums.AlbumID IN
-                                (SELECT CoreTracks.AlbumID FROM CoreTracks, CoreAlbums, CoreCache
+                                (SELECT CoreTracks.AlbumID FROM CoreTracks, CoreCache{1}
                                     WHERE CoreCache.ModelID = {0} AND
-                                          CoreCache.ItemId = CoreTracks.TrackID AND
-                                          CoreAlbums.AlbumID = CoreTracks.AlbumID)",
-                            track_model.CacheId
-                        ),
+                                          CoreCache.ItemId = {2})",
+                            track_model.CacheId,
+                            track_model.JoinFragment,
+                            track_model.JoinTable == null
+                                ? "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
                 );
@@ -139,5 +142,10 @@
         public string ReloadFragment {
             get { return reload_fragment; }
         }
+
+        public string JoinTable { get { return null; } }
+        public string JoinFragment { get { return null; } }
+        public string JoinPrimaryKey { get { return null; } }
+        public string JoinColumn { get { return null; } }
     }
 }

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	Mon Mar  3 16:37:57 2008
@@ -66,11 +66,19 @@
                     @"FROM CoreArtists {0} ORDER BY Name",
                     track_model != null ? String.Format(@"
                         WHERE CoreArtists.ArtistID IN
+                            (SELECT CoreTracks.ArtistID FROM CoreTracks, CoreCache{1}
+                                WHERE CoreCache.ModelID = {0} AND
+                                      CoreCache.ItemID = {2})",
+                        /*WHERE CoreArtists.ArtistID IN
                             (SELECT CoreTracks.ArtistID FROM CoreTracks, CoreArtists, CoreCache
                                 WHERE CoreCache.ModelID = {0} AND
-                                      CoreCache.ItemId = CoreTracks.TrackID AND
-                                      CoreArtists.ArtistId = CoreTracks.ArtistID)",
-                        track_model.CacheId
+                                      CoreCache.ItemID = CoreTracks.TrackID AND
+                                      CoreArtists.ArtistID = CoreTracks.ArtistID)",*/
+                        track_model.CacheId,
+                        track_model.JoinFragment,
+                        track_model.JoinTable == null
+                            ? "CoreTracks.TrackID"
+                            : String.Format ("{0}.{1} AND CoreTracks.TrackID = {0}.{2}", track_model.JoinTable, track_model.JoinPrimaryKey, track_model.JoinColumn)
                     ) : null
                 );
 
@@ -108,5 +116,10 @@
         public string ReloadFragment {
             get { return reload_fragment; }
         }
+
+        public string JoinTable { get { return null; } }
+        public string JoinFragment { get { return null; } }
+        public string JoinPrimaryKey { get { return null; } }
+        public string JoinColumn { get { return null; } }
     }
 }

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	Mon Mar  3 16:37:57 2008
@@ -49,7 +49,7 @@
     {
         private readonly BansheeDbConnection connection;
         private readonly BansheeModelProvider<DatabaseTrackInfo> provider;
-        private readonly BansheeModelCache<DatabaseTrackInfo> cache;
+        private BansheeModelCache<DatabaseTrackInfo> cache;
         private int count;
         private TimeSpan duration;
         private long filesize;
@@ -63,19 +63,31 @@
         private bool forced_sort_query;
         
         private string reload_fragment;
-        private string join_fragment, condition;
+        private string join_table, join_fragment, join_primary_key, join_column, condition;
 
         private string filter_query;
         private string filter;
         private string artist_id_filter_query;
         private string album_id_filter_query;
+
+        private string uuid;
         
         private int rows_in_view;
         
         public TrackListDatabaseModel (BansheeDbConnection connection, string uuid)
         {
             this.connection = connection;
+            this.uuid = uuid;
             provider = DatabaseTrackInfo.Provider;
+        }
+
+        private bool initialized = false;
+        public void Initialize ()
+        {
+            if (initialized)
+                return;
+
+            initialized = true;
             cache = new BansheeModelCache <DatabaseTrackInfo> (connection, uuid, this, provider);
             cache.AggregatesUpdated += HandleCacheAggregatesUpdated;
             Refilter ();
@@ -267,19 +279,32 @@
             }
         }
 
-        public string JoinFragment {
-            get { return join_fragment; }
+        public string JoinTable {
+            get { return join_table; }
             set {
-                join_fragment = value;
-                Refilter();
+                join_table = value;
+                join_fragment = String.Format (", {0}", join_table);
             }
         }
 
+        public string JoinFragment {
+            get { return join_fragment; }
+        }
+
+        public string JoinPrimaryKey {
+            get { return join_primary_key; }
+            set { join_primary_key = value; }
+        }
+
+        public string JoinColumn {
+            get { return join_column; }
+            set { join_column = value; }
+        }
+
         public string Condition {
             get { return condition; }
             set {
                 condition = value;
-                Refilter();
             }
         }
 

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	Mon Mar  3 16:37:57 2008
@@ -378,11 +378,13 @@
                 
             Execute(@"
                 CREATE TABLE CoreSmartPlaylistEntries (
+                    EntryID             INTEGER PRIMARY KEY,
                     SmartPlaylistID     INTEGER NOT NULL,
                     TrackID             INTEGER NOT NULL
                 )
             ");
-            Execute("CREATE INDEX CoreSmartPlaylistEntriesIndex ON CoreSmartPlaylistEntries(SmartPlaylistID, TrackID)");
+            Execute("CREATE INDEX CoreSmartPlaylistEntriesPlaylistIndex ON CoreSmartPlaylistEntries(EntryID, SmartPlaylistID)");
+            Execute("CREATE INDEX CoreSmartPlaylistEntriesTrackIndex ON CoreSmartPlaylistEntries(SmartPlaylistID, TrackID)");
 
             Execute(@"
                 CREATE TABLE CoreCacheModels (

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/AbstractPlaylistSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/AbstractPlaylistSource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/AbstractPlaylistSource.cs	Mon Mar  3 16:37:57 2008
@@ -54,10 +54,6 @@
         protected abstract string SourcePrimaryKey { get; }
         protected abstract string TrackJoinTable { get; }
 
-        protected virtual string TrackJoin {
-            get { return String.Format (", {0}", TrackJoinTable); }
-        }
-
         protected virtual string TrackCondition {
             get {
                 return String.Format (
@@ -67,6 +63,10 @@
             }
         }
 
+        protected virtual string JoinPrimaryKey {
+            get { return "EntryID"; }
+        }
+
         public int? DbId {
             get { return dbid; }
             protected set {
@@ -74,7 +74,9 @@
                     return;
                 }
                 dbid = value;
-                track_model.JoinFragment = TrackJoin;
+                track_model.JoinTable = TrackJoinTable;
+                track_model.JoinPrimaryKey = JoinPrimaryKey;
+                track_model.JoinColumn = "TrackID";
                 track_model.Condition = String.Format (TrackCondition, dbid);
                 AfterInitialized ();
             }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistSource.cs	Mon Mar  3 16:37:57 2008
@@ -54,6 +54,8 @@
         private static HyenaSqliteCommand add_track_range_command;
         private static HyenaSqliteCommand remove_track_range_command;
 
+        private static string add_track_range_from_joined_model_sql;
+
         private static string generic_name = Catalog.GetString ("Playlist");
 
         protected override string SourceTable {
@@ -76,6 +78,7 @@
 
             remove_track_command = new HyenaSqliteCommand (
                 "DELETE FROM CorePlaylistEntries WHERE PlaylistID = ? AND TrackID = ?"
+                //"DELETE FROM CorePlaylistEntries WHERE PlaylistID = ? AND EntryID = ?"
             );
 
             add_track_range_command = new HyenaSqliteCommand (@"
@@ -85,9 +88,16 @@
                         LIMIT ?, ?"
             );
 
+            add_track_range_from_joined_model_sql = @"
+                INSERT INTO CorePlaylistEntries
+                    SELECT null, ?, TrackID, 0
+                        FROM CoreCache c INNER JOIN {0} e ON c.ItemID = e.{1}
+                        WHERE ModelID = ?
+                        LIMIT ?, ?";
+
             remove_track_range_command = new HyenaSqliteCommand (@"
                 DELETE FROM CorePlaylistEntries WHERE PlaylistID = ? AND
-                    TrackID IN (SELECT ItemID FROM CoreCache
+                    EntryID IN (SELECT ItemID FROM CoreCache
                         WHERE ModelID = ? LIMIT ?, ?)"
             );
         }
@@ -236,17 +246,20 @@
             OnUserNotifyUpdated ();
         }
 
+        TrackListDatabaseModel last_add_range_from_model;
+        HyenaSqliteCommand last_add_range_command = null;
         protected virtual void AddTrackRange (TrackListDatabaseModel from, RangeCollection.Range range)
         {
-            add_track_range_command.ApplyValues (DbId, from.CacheId, range.Start, range.End - range.Start + 1);
-            ServiceManager.DbConnection.Execute (add_track_range_command);
-        }
+            last_add_range_command = (from.JoinTable == null)
+                ? add_track_range_command
+                : from == last_add_range_from_model
+                    ? last_add_range_command
+                    : new HyenaSqliteCommand (String.Format (add_track_range_from_joined_model_sql, from.JoinTable, from.JoinPrimaryKey));
 
-        public override void RemoveTrack (DatabaseTrackInfo track)
-        {
-            remove_track_command.ApplyValues (DbId, track.DbId);
-            ServiceManager.DbConnection.Execute (remove_track_command);
-            Reload ();
+            last_add_range_command.ApplyValues (DbId, from.CacheId, range.Start, range.End - range.Start + 1);
+            ServiceManager.DbConnection.Execute (last_add_range_command);
+
+            last_add_range_from_model = from;
         }
 
         protected override void RemoveTrackRange (TrackListDatabaseModel from, RangeCollection.Range range)

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	Mon Mar  3 16:37:57 2008
@@ -297,7 +297,7 @@
             // Repopulate it 
             ServiceManager.DbConnection.Execute (String.Format (
                 @"INSERT INTO CoreSmartPlaylistEntries 
-                    SELECT {0} as SmartPlaylistID, TrackId
+                    SELECT NULL, {0} as SmartPlaylistID, TrackId
                         FROM CoreTracks, CoreArtists, CoreAlbums
                         WHERE CoreTracks.ArtistID = CoreArtists.ArtistID AND CoreTracks.AlbumID = CoreAlbums.AlbumID
                         {1} {2}",

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	Mon Mar  3 16:37:57 2008
@@ -51,8 +51,6 @@
         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)
@@ -61,11 +59,6 @@
             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);
         }
 
@@ -178,12 +171,16 @@
 
         public virtual void RemoveTrack (int index)
         {
-            RemoveTrack (track_model [index] as DatabaseTrackInfo);
+            if (index != -1) {
+                RemoveTrackRange (track_model, new RangeCollection.Range (index, index));
+                Reload ();
+                ReloadChildren ();
+            }
         }
 
         public virtual void RemoveTrack (DatabaseTrackInfo track)
         {
-            throw new NotImplementedException(); 
+            RemoveTrack (track_model.IndexOf (track));
         }
 
         // Methods for removing tracks from this source
@@ -233,8 +230,8 @@
                 foreach (RangeCollection.Range range in selection.Ranges) {
                     RateTrackRange (model, range, rating);
                 }
-                Reload ();
-                ReloadChildren ();
+
+                ReloadPrimarySource ();
             }
         }
 
@@ -242,8 +239,55 @@
         
 #region Protected Methods
 
+        // If we are a PrimarySource, reload ourself and our children, otherwise if our Parent
+        // is one, do so for it, otherwise do so for all PrimarySources.
+        protected void ReloadPrimarySource ()
+        {
+            PrimarySource psource;
+            if ((psource = this as PrimarySource) != null) {
+                Reload ();
+                ReloadChildren ();
+            } else {
+                if ((psource = Parent as PrimarySource) != null) {
+                    psource.Reload ();
+                    psource.ReloadChildren ();
+                } else {
+                    foreach (Source source in ServiceManager.SourceManager.Sources) {
+                        if ((psource = source as PrimarySource) != null) {
+                            psource.Reload ();
+                            psource.ReloadChildren ();
+                        }
+                    }
+                }
+            }
+        }
+
+        protected HyenaSqliteCommand rate_track_range_command;
+        protected HyenaSqliteCommand RateTrackRangeCommand {
+            get {
+                if (rate_track_range_command == null) {
+                    if (track_model.JoinTable != null) {
+                        rate_track_range_command = new HyenaSqliteCommand (String.Format (@"
+                            UPDATE CoreTracks SET Rating = ? WHERE
+                                TrackID IN (SELECT TrackID FROM {0} WHERE 
+                                    {1} IN (SELECT ItemID FROM CoreCache WHERE ModelID = {2} LIMIT ?, ?))",
+                            track_model.JoinTable, track_model.JoinPrimaryKey, track_model.CacheId
+                        ));
+                    } else {
+                        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
+                        ));
+                    }
+                }
+                return rate_track_range_command;
+            }
+        }
+
         protected void AfterInitialized ()
         {
+            track_model.Initialize ();
             Reload ();
             OnSetupComplete ();
         }
@@ -261,8 +305,8 @@
 
         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);
+            RateTrackRangeCommand.ApplyValues (rating, range.Start, range.End - range.Start + 1);
+            ServiceManager.DbConnection.Execute (RateTrackRangeCommand);
         }
 
         protected void WithTrackSelection (TrackListDatabaseModel model, TrackRangeHandler handler)

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	Mon Mar  3 16:37:57 2008
@@ -137,14 +137,6 @@
             }
         }
 
-        public override void RemoveTrack (DatabaseTrackInfo track)
-        {
-            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/Libraries/Hyena/Hyena.Data.Sqlite/ICacheableDatabaseModel.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/ICacheableDatabaseModel.cs	(original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/ICacheableDatabaseModel.cs	Mon Mar  3 16:37:57 2008
@@ -36,5 +36,9 @@
     {
         string ReloadFragment { get; }
         string SelectAggregates { get; }
+        string JoinTable { get; }
+        string JoinFragment { get; }
+        string JoinPrimaryKey { get; }
+        string JoinColumn { get; }
     }
 }

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	Mon Mar  3 16:37:57 2008
@@ -64,11 +64,25 @@
             CheckCacheTable ();
 
             if (model.SelectAggregates != null) {
-                count_command = new HyenaSqliteCommand (String.Format (@"
-                    SELECT COUNT(*), {0} FROM {1} WHERE {2}
-                        IN (SELECT ItemID FROM {3} WHERE ModelID = ?)",
-                    model.SelectAggregates, provider.TableName, provider.PrimaryKey, CacheTableName
-                ));
+                if (model.JoinFragment != null) {
+                    count_command = new HyenaSqliteCommand (String.Format (@"
+                        SELECT count(*), {0} FROM {1}{2} j
+                        WHERE j.{4} IN (SELECT ItemID FROM {3} WHERE ModelID = ?)
+                        AND {5} = j.{6}",
+                        model.SelectAggregates, // eg sum(FileSize), sum(Duration)
+                        provider.TableName,     // eg CoreTracks
+                        model.JoinFragment,     // eg , CorePlaylistEntries
+                        CacheTableName,         // eg CoreCache
+                        model.JoinPrimaryKey,   // eg EntryID
+                        provider.PrimaryKey,    // eg CoreTracks.TrackID
+                        model.JoinColumn        // eg TrackID
+                    ));
+                } else {
+                    count_command = new HyenaSqliteCommand (String.Format (
+                        "SELECT count(*), {0} FROM {1} WHERE {2} IN (SELECT ItemID FROM {3} WHERE ModelID = ?)",
+                        model.SelectAggregates, provider.TableName, provider.PrimaryKey, CacheTableName
+                    ));
+                }
             } else {
                 count_command = new HyenaSqliteCommand (String.Format (
                     "SELECT COUNT(*) FROM {0} WHERE ModelID = ?", CacheTableName
@@ -77,31 +91,74 @@
 
             FindOrCreateCacheModelId (String.Format ("{0}-{1}", uuid, typeof(T).Name));
 
-            select_range_command = new HyenaSqliteCommand (
-                String.Format (@"
-                    SELECT {0} FROM {1}
-                        INNER JOIN {2}
-                            ON {3} = {2}.ItemID
-                        WHERE
-                            {2}.ModelID = {4} {5}
-                            {6}
-                        LIMIT ?, ?",
-                    provider.Select, provider.From, CacheTableName,
-                    provider.PrimaryKey, uid,
-                    String.IsNullOrEmpty (provider.Where) ? String.Empty : "AND",
-                    provider.Where
-                )
-            );
+            if (model.JoinFragment != null) {
+                select_range_command = new HyenaSqliteCommand (
+                    String.Format (@"
+                        SELECT {0} FROM {1}
+                            INNER JOIN {2}
+                                ON {3} = {2}.{4}
+                            INNER JOIN {5}
+                                ON {2}.{6} = {5}.ItemID
+                            WHERE
+                                {5}.ModelID = {7} {8}
+                                {9}
+                            LIMIT ?, ?",
+                        provider.Select, provider.From,
+                        model.JoinTable, provider.PrimaryKey, model.JoinColumn,
+                        CacheTableName, model.JoinPrimaryKey, uid,
+                        String.IsNullOrEmpty (provider.Where) ? null : "AND",
+                        provider.Where
+                    )
+                );
+
+                select_single_command = new HyenaSqliteCommand (
+                    String.Format (@"
+                        SELECT OrderID FROM {0}
+                            WHERE
+                                ModelID = {1} AND
+                                ItemID = (SELECT {2} FROM {3} WHERE {4} = ?)",
+                        CacheTableName, uid, model.JoinPrimaryKey, model.JoinTable, model.JoinColumn
+                    )
+                );
+
+                reload_sql = String.Format (@"
+                    DELETE FROM {0} WHERE ModelID = {1};
+                        INSERT INTO {0} SELECT null, {1}, {2} ",
+                    CacheTableName, uid, model.JoinPrimaryKey
+                );
+            } else {
+                select_range_command = new HyenaSqliteCommand (
+                    String.Format (@"
+                        SELECT {0} FROM {1}
+                            INNER JOIN {2}
+                                ON {3} = {2}.ItemID
+                            WHERE
+                                {2}.ModelID = {4} {5}
+                                {6}
+                            LIMIT ?, ?",
+                        provider.Select, provider.From, CacheTableName,
+                        provider.PrimaryKey, uid,
+                        String.IsNullOrEmpty (provider.Where) ? String.Empty : "AND",
+                        provider.Where
+                    )
+                );
             
-            select_single_command = new HyenaSqliteCommand (
-                String.Format (@"
-                    SELECT OrderID FROM {0}
-                        WHERE
-                            ModelID = {1} AND
-                            ItemID = ?",
-                    CacheTableName, uid
-                )
-            );
+                select_single_command = new HyenaSqliteCommand (
+                    String.Format (@"
+                        SELECT OrderID FROM {0}
+                            WHERE
+                                ModelID = {1} AND
+                                ItemID = ?",
+                        CacheTableName, uid
+                    )
+                );
+
+                reload_sql = String.Format (@"
+                    DELETE FROM {0} WHERE ModelID = {1};
+                        INSERT INTO {0} SELECT null, {1}, {2} ",
+                    CacheTableName, uid, provider.PrimaryKey
+                );
+            }
             
             select_first_command = new HyenaSqliteCommand (
                 String.Format (
@@ -110,11 +167,6 @@
                 )
             );
 
-            reload_sql = String.Format (@"
-                DELETE FROM {0} WHERE ModelID = {1};
-                    INSERT INTO {0} SELECT null, {1}, {2} ",
-                CacheTableName, uid, provider.PrimaryKey
-            );
         }
 
         public bool Warm {



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