use a single query for retrieving playcounts to speed up file listings
authorJonathan Marshall <jmarshall@never.you.mind>
Thu, 28 Apr 2011 22:23:32 +0000 (10:23 +1200)
committerJonathan Marshall <jmarshall@never.you.mind>
Thu, 28 Apr 2011 22:23:32 +0000 (10:23 +1200)
xbmc/video/VideoDatabase.cpp
xbmc/video/VideoDatabase.h
xbmc/video/windows/GUIWindowVideoNav.cpp

index 2c79ec3..8552594 100644 (file)
@@ -3495,6 +3495,42 @@ void CVideoDatabase::UpdateBasePath(const char *table, const char *id, int colum
   m_pDS2->close();
 }
 
+bool CVideoDatabase::GetPlayCounts(CFileItemList &items)
+{
+  int pathID = GetPathId(items.m_strPath);
+  if (pathID < 0)
+    return false; // path (and thus files) aren't in the database
+
+  try
+  {
+    // error!
+    if (NULL == m_pDB.get()) return false;
+    if (NULL == m_pDS.get()) return false;
+
+    // TODO: also test a single query for the above and below
+    CStdString sql = PrepareSQL("select strFilename,playCount from files where idPath=%i", pathID);
+    if (RunQuery(sql) <= 0)
+      return false;
+
+    items.SetFastLookup(true); // note: it's possibly quicker the other way around (map on db returned items)?
+    while (!m_pDS->eof())
+    {
+      CStdString path;
+      ConstructPath(path, items.m_strPath, m_pDS->fv(0).get_asString());
+      CFileItemPtr item = items.Get(path);
+      if (item)
+        item->GetVideoInfoTag()->m_playCount = m_pDS->fv(1).get_asInt();
+      m_pDS->next();
+    }
+    return true;
+  }
+  catch (...)
+  {
+    CLog::Log(LOGERROR, "%s failed", __FUNCTION__);
+  }
+  return false;
+}
+
 int CVideoDatabase::GetPlayCount(const CFileItem &item)
 {
   int id = GetFileId(item);
index ab3d0f1..15f05f4 100644 (file)
@@ -328,24 +328,30 @@ public:
   /*! \brief Increment the playcount of an item
    Increments the playcount and updates the last played date
    \param item CFileItem to increment the playcount for
-   \sa GetPlayCount, SetPlayCount
+   \sa GetPlayCount, SetPlayCount, GetPlayCounts
    */
   void IncrementPlayCount(const CFileItem &item);
 
   /*! \brief Get the playcount of an item
    \param item CFileItem to get the playcount for
    \return the playcount of the item, or -1 on error
-   \sa SetPlayCount, IncrementPlayCount
+   \sa SetPlayCount, IncrementPlayCount, GetPlayCounts
    */
   int GetPlayCount(const CFileItem &item);
 
   /*! \brief Update the last played time of an item
    Updates the last played date
    \param item CFileItem to update the last played time for
-   \sa GetPlayCount, SetPlayCount, IncrementPlayCount
+   \sa GetPlayCount, SetPlayCount, IncrementPlayCount, GetPlayCounts
    */
   void UpdateLastPlayed(const CFileItem &item);
 
+  /*! \brief Get the playcount of a list of items
+   \param items CFileItemList to fetch the playcounts for
+   \sa GetPlayCount, SetPlayCount, IncrementPlayCount
+   */
+  bool GetPlayCounts(CFileItemList &items);
+
   void UpdateMovieTitle(int idMovie, const CStdString& strNewMovieTitle, VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES);
 
   bool HasMovieInfo(const CStdString& strFilenameAndPath);
index 0077dfc..01bab1d 100644 (file)
@@ -419,6 +419,9 @@ void CGUIWindowVideoNav::LoadVideoInfo(CFileItemList &items)
                 !items.IsVirtualDirectoryRoot() &&
                 m_stackingAvailable);
 
+  if (content.IsEmpty())
+    m_database.GetPlayCounts(items);
+
   for (int i = 0; i < items.Size(); i++)
   {
     CFileItemPtr pItem = items[i];
@@ -434,10 +437,9 @@ void CGUIWindowVideoNav::LoadVideoInfo(CFileItemList &items)
       pItem->m_bIsFolder = item.m_bIsFolder;
     }
     else
-    { // grab the playcount and clean the label
-      int playCount = m_database.GetPlayCount(*pItem);
-      if (playCount >= 0)
-        pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, playCount > 0);
+    { // set the watched overlay and clean the label
+      if (pItem->HasVideoInfoTag())
+        pItem->SetOverlayImage(CGUIListItem::ICON_OVERLAY_UNWATCHED, pItem->GetVideoInfoTag()->m_playCount > 0);
       if (clean)
         pItem->CleanString();
     }