added: index to the basePath columns for faster retrieval
[vuplus_xbmc] / xbmc / video / VideoDatabase.h
1 #pragma once
2 /*
3  *      Copyright (C) 2005-2008 Team XBMC
4  *      http://www.xbmc.org
5  *
6  *  This Program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2, or (at your option)
9  *  any later version.
10  *
11  *  This Program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with XBMC; see the file COPYING.  If not, write to
18  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19  *  http://www.gnu.org/copyleft/gpl.html
20  *
21  */
22 #include "dbwrappers/Database.h"
23 #include "VideoInfoTag.h"
24 #include "addons/Scraper.h"
25 #include "Bookmark.h"
26
27 #include <memory>
28 #include <set>
29
30 class CFileItem;
31 class CFileItemList;
32 class CVideoSettings;
33 class CGUIDialogProgress;
34
35 #ifndef my_offsetof
36 #ifndef _LINUX
37 #define my_offsetof(TYPE, MEMBER) offsetof(TYPE, MEMBER)
38 #else
39 /*
40    Custom version of standard offsetof() macro which can be used to get
41    offsets of members in class for non-POD types (according to the current
42    version of C++ standard offsetof() macro can't be used in such cases and
43    attempt to do so causes warnings to be emitted, OTOH in many cases it is
44    still OK to assume that all instances of the class has the same offsets
45    for the same members).
46  */
47 #define my_offsetof(TYPE, MEMBER) \
48                ((size_t)((char *)&(((TYPE *)0x10)->MEMBER) - (char*)0x10))
49 #endif
50 #endif
51
52 typedef std::vector<CVideoInfoTag> VECMOVIES;
53
54 namespace VIDEO
55 {
56   class IVideoInfoScannerObserver;
57   struct SScanSettings;
58 }
59
60 // these defines are based on how many columns we have and which column certain data is going to be in
61 // when we do GetDetailsForMovie()
62 #define VIDEODB_MAX_COLUMNS 23
63 #define VIDEODB_DETAILS_FILEID                  1
64 #define VIDEODB_DETAILS_FILE                    VIDEODB_MAX_COLUMNS + 2
65 #define VIDEODB_DETAILS_PATH                    VIDEODB_MAX_COLUMNS + 3
66 #define VIDEODB_DETAILS_PLAYCOUNT               VIDEODB_MAX_COLUMNS + 4
67 #define VIDEODB_DETAILS_LASTPLAYED              VIDEODB_MAX_COLUMNS + 5
68 #define VIDEODB_DETAILS_EPISODE_TVSHOW_NAME     VIDEODB_MAX_COLUMNS + 6
69 #define VIDEODB_DETAILS_EPISODE_TVSHOW_STUDIO   VIDEODB_MAX_COLUMNS + 7
70 #define VIDEODB_DETAILS_EPISODE_TVSHOW_ID       VIDEODB_MAX_COLUMNS + 8
71 #define VIDEODB_DETAILS_EPISODE_TVSHOW_AIRED    VIDEODB_MAX_COLUMNS + 9
72 #define VIDEODB_DETAILS_EPISODE_TVSHOW_MPAA     VIDEODB_MAX_COLUMNS + 10
73                                                 
74 #define VIDEODB_DETAILS_TVSHOW_PATH             VIDEODB_MAX_COLUMNS + 1
75 #define VIDEODB_DETAILS_TVSHOW_NUM_EPISODES     VIDEODB_MAX_COLUMNS + 2
76 #define VIDEODB_DETAILS_TVSHOW_NUM_WATCHED      VIDEODB_MAX_COLUMNS + 3
77 #define VIDEODB_DETAILS_TVSHOW_NUM_SEASONS      VIDEODB_MAX_COLUMNS + 4
78
79
80 #define VIDEODB_TYPE_STRING 1
81 #define VIDEODB_TYPE_INT 2
82 #define VIDEODB_TYPE_FLOAT 3
83 #define VIDEODB_TYPE_BOOL 4
84 #define VIDEODB_TYPE_COUNT 5
85
86 typedef enum
87 {
88   VIDEODB_CONTENT_MOVIES = 1,
89   VIDEODB_CONTENT_TVSHOWS = 2,
90   VIDEODB_CONTENT_MUSICVIDEOS = 3,
91   VIDEODB_CONTENT_EPISODES = 4,
92   VIDEODB_CONTENT_MOVIE_SETS = 5
93 } VIDEODB_CONTENT_TYPE;
94
95 typedef enum // this enum MUST match the offset struct further down!! and make sure to keep min and max at -1 and sizeof(offsets)
96 {
97   VIDEODB_ID_MIN = -1,
98   VIDEODB_ID_TITLE = 0,
99   VIDEODB_ID_PLOT = 1,
100   VIDEODB_ID_PLOTOUTLINE = 2,
101   VIDEODB_ID_TAGLINE = 3,
102   VIDEODB_ID_VOTES = 4,
103   VIDEODB_ID_RATING = 5,
104   VIDEODB_ID_CREDITS = 6,
105   VIDEODB_ID_YEAR = 7,
106   VIDEODB_ID_THUMBURL = 8,
107   VIDEODB_ID_IDENT = 9,
108   VIDEODB_ID_SORTTITLE = 10,
109   VIDEODB_ID_RUNTIME = 11,
110   VIDEODB_ID_MPAA = 12,
111   VIDEODB_ID_TOP250 = 13,
112   VIDEODB_ID_GENRE = 14,
113   VIDEODB_ID_DIRECTOR = 15,
114   VIDEODB_ID_ORIGINALTITLE = 16,
115   VIDEODB_ID_THUMBURL_SPOOF = 17,
116   VIDEODB_ID_STUDIOS = 18,
117   VIDEODB_ID_TRAILER = 19,
118   VIDEODB_ID_FANART = 20,
119   VIDEODB_ID_COUNTRY = 21,
120   VIDEODB_ID_BASEPATH = 22,
121   VIDEODB_ID_MAX
122 } VIDEODB_IDS;
123
124 const struct SDbTableOffsets
125 {
126   int type;
127   size_t offset;
128 } DbMovieOffsets[] =
129 {
130   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTitle) },
131   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlot) },
132   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlotOutline) },
133   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTagLine) },
134   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strVotes) },
135   { VIDEODB_TYPE_FLOAT, my_offsetof(CVideoInfoTag,m_fRating) },
136   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strWritingCredits) },
137   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iYear) },
138   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_xml) },
139   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strIMDBNumber) },
140   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strSortTitle) },
141   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strRuntime) },
142   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strMPAARating) },
143   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iTop250) },
144   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strGenre) },
145   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strDirector) },
146   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strOriginalTitle) },
147   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_spoof) },
148   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strStudio) },
149   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTrailer) },
150   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_fanart.m_xml) },
151   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strCountry) },
152   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_basePath) }
153 };
154
155 typedef enum // this enum MUST match the offset struct further down!! and make sure to keep min and max at -1 and sizeof(offsets)
156 {
157   VIDEODB_ID_TV_MIN = -1,
158   VIDEODB_ID_TV_TITLE = 0,
159   VIDEODB_ID_TV_PLOT = 1,
160   VIDEODB_ID_TV_STATUS = 2,
161   VIDEODB_ID_TV_VOTES = 3,
162   VIDEODB_ID_TV_RATING = 4,
163   VIDEODB_ID_TV_PREMIERED = 5,
164   VIDEODB_ID_TV_THUMBURL = 6,
165   VIDEODB_ID_TV_THUMBURL_SPOOF = 7,
166   VIDEODB_ID_TV_GENRE = 8,
167   VIDEODB_ID_TV_ORIGINALTITLE = 9,
168   VIDEODB_ID_TV_EPISODEGUIDE = 10,
169   VIDEODB_ID_TV_FANART = 11,
170   VIDEODB_ID_TV_IDENT = 12,
171   VIDEODB_ID_TV_MPAA = 13,
172   VIDEODB_ID_TV_STUDIOS = 14,
173   VIDEODB_ID_TV_SORTTITLE = 15,
174   VIDEODB_ID_TV_BASEPATH = 16,
175   VIDEODB_ID_TV_MAX
176 } VIDEODB_TV_IDS;
177
178 const struct SDbTableOffsets DbTvShowOffsets[] =
179 {
180   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTitle) },
181   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlot) },
182   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strStatus) },
183   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strVotes) },
184   { VIDEODB_TYPE_FLOAT, my_offsetof(CVideoInfoTag,m_fRating) },
185   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPremiered) },
186   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_xml) },
187   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_spoof) },
188   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strGenre) },
189   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strOriginalTitle)},
190   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strEpisodeGuide)},
191   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_fanart.m_xml)},
192   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strIMDBNumber)},
193   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strMPAARating)},
194   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strStudio)},
195   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strSortTitle)},
196   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_basePath) }
197 };
198
199 typedef enum // this enum MUST match the offset struct further down!! and make sure to keep min and max at -1 and sizeof(offsets)
200 {
201   VIDEODB_ID_EPISODE_MIN = -1,
202   VIDEODB_ID_EPISODE_TITLE = 0,
203   VIDEODB_ID_EPISODE_PLOT = 1,
204   VIDEODB_ID_EPISODE_VOTES = 2,
205   VIDEODB_ID_EPISODE_RATING = 3,
206   VIDEODB_ID_EPISODE_CREDITS = 4,
207   VIDEODB_ID_EPISODE_AIRED = 5,
208   VIDEODB_ID_EPISODE_THUMBURL = 6,
209   VIDEODB_ID_EPISODE_THUMBURL_SPOOF = 7,
210   VIDEODB_ID_EPISODE_PLAYCOUNT = 8, // unused - feel free to repurpose
211   VIDEODB_ID_EPISODE_RUNTIME = 9,
212   VIDEODB_ID_EPISODE_DIRECTOR = 10,
213   VIDEODB_ID_EPISODE_IDENT = 11,
214   VIDEODB_ID_EPISODE_SEASON = 12,
215   VIDEODB_ID_EPISODE_EPISODE = 13,
216   VIDEODB_ID_EPISODE_ORIGINALTITLE = 14,
217   VIDEODB_ID_EPISODE_SORTSEASON = 15,
218   VIDEODB_ID_EPISODE_SORTEPISODE = 16,
219   VIDEODB_ID_EPISODE_BOOKMARK = 17,
220   VIDEODB_ID_EPISODE_BASEPATH = 18,
221   VIDEODB_ID_EPISODE_MAX
222 } VIDEODB_EPISODE_IDS;
223
224 const struct SDbTableOffsets DbEpisodeOffsets[] =
225 {
226   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTitle) },
227   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlot) },
228   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strVotes) },
229   { VIDEODB_TYPE_FLOAT, my_offsetof(CVideoInfoTag,m_fRating) },
230   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strWritingCredits) },
231   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strFirstAired) },
232   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_xml) },
233   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_spoof) },
234   { VIDEODB_TYPE_COUNT, my_offsetof(CVideoInfoTag,m_playCount) }, // unused
235   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strRuntime) },
236   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strDirector) },
237   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strProductionCode) },
238   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iSeason) },
239   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iEpisode) },
240   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strOriginalTitle)},
241   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iSpecialSortSeason) },
242   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iSpecialSortEpisode) },
243   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iBookmarkId) },
244   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_basePath) }
245 };
246
247 typedef enum // this enum MUST match the offset struct further down!! and make sure to keep min and max at -1 and sizeof(offsets)
248 {
249   VIDEODB_ID_MUSICVIDEO_MIN = -1,
250   VIDEODB_ID_MUSICVIDEO_TITLE = 0,
251   VIDEODB_ID_MUSICVIDEO_THUMBURL = 1,
252   VIDEODB_ID_MUSICVIDEO_THUMBURL_SPOOF = 2,
253   VIDEODB_ID_MUSICVIDEO_PLAYCOUNT = 3, // unused - feel free to repurpose
254   VIDEODB_ID_MUSICVIDEO_RUNTIME = 4,
255   VIDEODB_ID_MUSICVIDEO_DIRECTOR = 5,
256   VIDEODB_ID_MUSICVIDEO_STUDIOS = 6,
257   VIDEODB_ID_MUSICVIDEO_YEAR = 7,
258   VIDEODB_ID_MUSICVIDEO_PLOT = 8,
259   VIDEODB_ID_MUSICVIDEO_ALBUM = 9,
260   VIDEODB_ID_MUSICVIDEO_ARTIST = 10,
261   VIDEODB_ID_MUSICVIDEO_GENRE = 11,
262   VIDEODB_ID_MUSICVIDEO_TRACK = 12,
263   VIDEODB_ID_MUSICVIDEO_BASEPATH = 13,
264   VIDEODB_ID_MUSICVIDEO_MAX
265 } VIDEODB_MUSICVIDEO_IDS;
266
267 const struct SDbTableOffsets DbMusicVideoOffsets[] =
268 {
269   { VIDEODB_TYPE_STRING, my_offsetof(class CVideoInfoTag,m_strTitle) },
270   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_xml) },
271   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_spoof) },
272   { VIDEODB_TYPE_COUNT, my_offsetof(CVideoInfoTag,m_playCount) }, // unused
273   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strRuntime) },
274   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strDirector) },
275   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strStudio) },
276   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iYear) },
277   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlot) },
278   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strAlbum) },
279   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strArtist) },
280   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strGenre) },
281   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iTrack) },
282   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_basePath) }
283 };
284
285 #define COMPARE_PERCENTAGE     0.90f // 90%
286 #define COMPARE_PERCENTAGE_MIN 0.50f // 50%
287
288 class CVideoDatabase : public CDatabase
289 {
290 public:
291
292   class CActor    // used for actor retrieval for non-master users
293   {
294   public:
295     CStdString name;
296     CStdString thumb;
297     int playcount;
298   };
299
300   class CSeason   // used for season retrieval for non-master users
301   {
302   public:
303     CStdString path;
304     CStdString genre;
305     int numEpisodes;
306     int numWatched;
307   };
308
309   CVideoDatabase(void);
310   virtual ~CVideoDatabase(void);
311
312   virtual bool Open();
313   virtual bool CommitTransaction();
314
315   int AddMovie(const CStdString& strFilenameAndPath);
316   int AddEpisode(int idShow, const CStdString& strFilenameAndPath);
317
318   // editing functions
319   /*! \brief Set the playcount of an item
320    Sets the playcount and last played date to a given value
321    \param item CFileItem to set the playcount for
322    \param count The playcount to set.
323    \param date The date the file was last viewed (does not denote the video was watched to completion).  If empty we current datetime (if count > 0) or never viewed (if count = 0).
324    \sa GetPlayCount, IncrementPlayCount, UpdateLastPlayed
325    */
326   void SetPlayCount(const CFileItem &item, int count, const CStdString &date = "");
327
328   /*! \brief Increment the playcount of an item
329    Increments the playcount and updates the last played date
330    \param item CFileItem to increment the playcount for
331    \sa GetPlayCount, SetPlayCount
332    */
333   void IncrementPlayCount(const CFileItem &item);
334
335   /*! \brief Get the playcount of an item
336    \param item CFileItem to get the playcount for
337    \return the playcount of the item, or -1 on error
338    \sa SetPlayCount, IncrementPlayCount
339    */
340   int GetPlayCount(const CFileItem &item);
341
342   /*! \brief Update the last played time of an item
343    Updates the last played date
344    \param item CFileItem to update the last played time for
345    \sa GetPlayCount, SetPlayCount, IncrementPlayCount
346    */
347   void UpdateLastPlayed(const CFileItem &item);
348
349   void UpdateMovieTitle(int idMovie, const CStdString& strNewMovieTitle, VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES);
350
351   bool HasMovieInfo(const CStdString& strFilenameAndPath);
352   bool HasTvShowInfo(const CStdString& strFilenameAndPath);
353   bool HasEpisodeInfo(const CStdString& strFilenameAndPath);
354   bool HasMusicVideoInfo(const CStdString& strFilenameAndPath);
355
356   void GetFilePathById(int idMovie, CStdString &filePath, VIDEODB_CONTENT_TYPE iType);
357   bool GetGenreById(int idGenre, CStdString& strGenre);
358   bool GetCountryById(int idCountry, CStdString& strCountry);
359   bool GetSetById(int idSet, CStdString& strSet);
360   int GetTvShowForEpisode(int idEpisode);
361
362   void GetMovieInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idMovie = -1);
363   void GetTvShowInfo(const CStdString& strPath, CVideoInfoTag& details, int idTvShow = -1);
364   bool GetEpisodeInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idEpisode = -1);
365   void GetMusicVideoInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idMVideo=-1);
366   bool GetStreamDetailsForFileId(CStreamDetails& details, int idFile) const;
367
368   int GetPathId(const CStdString& strPath);
369   int GetTvShowId(const CStdString& strPath);
370   int GetEpisodeId(const CStdString& strFilenameAndPath, int idEpisode=-1, int idSeason=-1); // idEpisode, idSeason are used for multipart episodes as hints
371
372   void GetEpisodesByFile(const CStdString& strFilenameAndPath, std::vector<CVideoInfoTag>& episodes);
373
374   int SetDetailsForMovie(const CStdString& strFilenameAndPath, const CVideoInfoTag& details);
375   int SetDetailsForTvShow(const CStdString& strPath, const CVideoInfoTag& details);
376   int SetDetailsForEpisode(const CStdString& strFilenameAndPath, const CVideoInfoTag& details, int idShow, int idEpisode=-1);
377   int SetDetailsForMusicVideo(const CStdString& strFilenameAndPath, const CVideoInfoTag& details);
378   void SetStreamDetailsForFile(const CStreamDetails& details, const CStdString &strFileNameAndPath);
379   void SetStreamDetailsForFileId(const CStreamDetails& details, int idFile);
380   void SetDetail(const CStdString& strDetail, int id, int field, VIDEODB_CONTENT_TYPE type);
381
382   void DeleteMovie(const CStdString& strFilenameAndPath, bool bKeepId = false, bool bKeepThumb = false);
383   void DeleteTvShow(const CStdString& strPath, bool bKeepId = false, bool bKeepThumb = false);
384   void DeleteEpisode(const CStdString& strFilenameAndPath, int idEpisode = -1, bool bKeepId = false, bool bKeepThumb = false);
385   void DeleteMusicVideo(const CStdString& strFilenameAndPath, bool bKeepId = false, bool bKeepThumb = false);
386   void DeleteDetailsForTvShow(const CStdString& strPath);
387   void RemoveContentForPath(const CStdString& strPath,CGUIDialogProgress *progress = NULL);
388   void UpdateFanart(const CFileItem &item, VIDEODB_CONTENT_TYPE type);
389   void DeleteSet(int idSet);
390
391   // per-file video settings
392   bool GetVideoSettings(const CStdString &strFilenameAndPath, CVideoSettings &settings);
393   void SetVideoSettings(const CStdString &strFilenameAndPath, const CVideoSettings &settings);
394   void EraseVideoSettings();
395
396   bool GetStackTimes(const CStdString &filePath, std::vector<int> &times);
397   void SetStackTimes(const CStdString &filePath, std::vector<int> &times);
398
399   void GetBookMarksForFile(const CStdString& strFilenameAndPath, VECBOOKMARKS& bookmarks, CBookmark::EType type = CBookmark::STANDARD, bool bAppend=false);
400   void AddBookMarkToFile(const CStdString& strFilenameAndPath, const CBookmark &bookmark, CBookmark::EType type = CBookmark::STANDARD);
401   bool GetResumeBookMark(const CStdString& strFilenameAndPath, CBookmark &bookmark);
402   void DeleteResumeBookMark(const CStdString &strFilenameAndPath);
403   void ClearBookMarkOfFile(const CStdString& strFilenameAndPath, CBookmark& bookmark, CBookmark::EType type = CBookmark::STANDARD);
404   void ClearBookMarksOfFile(const CStdString& strFilenameAndPath, CBookmark::EType type = CBookmark::STANDARD);
405   bool GetBookMarkForEpisode(const CVideoInfoTag& tag, CBookmark& bookmark);
406   void AddBookMarkForEpisode(const CVideoInfoTag& tag, const CBookmark& bookmark);
407   void DeleteBookMarkForEpisode(const CVideoInfoTag& tag);
408
409   // scraper settings
410   void SetScraperForPath(const CStdString& filePath, const ADDON::ScraperPtr& info, const VIDEO::SScanSettings& settings);
411   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath);
412   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath, VIDEO::SScanSettings& settings);
413
414   /*! \brief Retrieve the scraper and settings we should use for the specified path
415    If the scraper is not set on this particular path, we'll recursively check parent folders.
416    \param strPath path to start searching in.
417    \param settings [out] scan settings for this folder.
418    \param foundDirectly [out] true if a scraper was found directly for strPath, false if it was in a parent path.
419    \return A ScraperPtr containing the scraper information. Returns NULL if a trivial (Content == CONTENT_NONE)
420            scraper or no scraper is found.
421    */
422   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath, VIDEO::SScanSettings& settings, bool& foundDirectly);
423
424   /*! \brief Retrieve the content type of videos in the given path
425    If content is set on the folder, we return the given content type, except in the case of tvshows,
426    where we first check for whether we have episodes directly in the path (thus return episodes) or whether
427    we've found a scraper directly (shows).  Any folders inbetween are treated as seasons (regardless of whether
428    they actually are seasons). Note that any subfolders in movies will be treated as movies.
429    \param strPath path to start searching in.
430    \return A content type string for the current path.
431    */
432   CStdString GetContentForPath(const CStdString& strPath);
433   
434   /*! \brief Check whether a given scraper is in use.
435    \param scraperID the scraper to check for.
436    \return true if the scraper is in use, false otherwise.
437    */
438   bool ScraperInUse(const CStdString &scraperID) const;
439   
440   // scanning hashes and paths scanned
441   bool SetPathHash(const CStdString &path, const CStdString &hash);
442   bool GetPathHash(const CStdString &path, CStdString &hash);
443   bool GetPaths(std::set<CStdString> &paths);
444   bool GetPathsForTvShow(int idShow, std::vector<int>& paths);
445
446   /*! \brief retrieve subpaths of a given path.  Assumes a heirarchical folder structure
447    \param basepath the root path to retrieve subpaths for
448    \param subpaths the returned subpaths
449    \return true if we successfully retrieve subpaths (may be zero), false on error
450    */
451   bool GetSubPaths(const CStdString& basepath, std::vector<int>& subpaths);
452
453   // for music + musicvideo linkups - if no album and title given it will return the artist id, else the id of the matching video
454   int GetMatchingMusicVideo(const CStdString& strArtist, const CStdString& strAlbum = "", const CStdString& strTitle = "");
455
456   // searching functions
457   void GetMoviesByActor(const CStdString& strActor, CFileItemList& items);
458   void GetTvShowsByActor(const CStdString& strActor, CFileItemList& items);
459   void GetEpisodesByActor(const CStdString& strActor, CFileItemList& items);
460
461   void GetMusicVideosByArtist(const CStdString& strArtist, CFileItemList& items);
462   void GetMusicVideosByAlbum(const CStdString& strAlbum, CFileItemList& items);
463
464   void GetMovieGenresByName(const CStdString& strSearch, CFileItemList& items);
465   void GetTvShowGenresByName(const CStdString& strSearch, CFileItemList& items);
466   void GetMusicVideoGenresByName(const CStdString& strSearch, CFileItemList& items);
467
468   void GetMovieCountriesByName(const CStdString& strSearch, CFileItemList& items);
469
470   void GetMusicVideoAlbumsByName(const CStdString& strSearch, CFileItemList& items);
471
472   void GetMovieActorsByName(const CStdString& strSearch, CFileItemList& items);
473   void GetTvShowsActorsByName(const CStdString& strSearch, CFileItemList& items);
474   void GetMusicVideoArtistsByName(const CStdString& strSearch, CFileItemList& items);
475
476   void GetMovieDirectorsByName(const CStdString& strSearch, CFileItemList& items);
477   void GetTvShowsDirectorsByName(const CStdString& strSearch, CFileItemList& items);
478   void GetMusicVideoDirectorsByName(const CStdString& strSearch, CFileItemList& items);
479
480   void GetMoviesByName(const CStdString& strSearch, CFileItemList& items);
481   void GetTvShowsByName(const CStdString& strSearch, CFileItemList& items);
482   void GetEpisodesByName(const CStdString& strSearch, CFileItemList& items);
483   void GetMusicVideosByName(const CStdString& strSearch, CFileItemList& items);
484
485   void GetEpisodesByPlot(const CStdString& strSearch, CFileItemList& items);
486   void GetMoviesByPlot(const CStdString& strSearch, CFileItemList& items);
487
488   bool LinkMovieToTvshow(int idMovie, int idShow, bool bRemove);
489   bool IsLinkedToTvshow(int idMovie);
490   bool GetLinksToTvShow(int idMovie, std::vector<int>& ids);
491
492   bool GetArbitraryQuery(const CStdString& strQuery, const CStdString& strOpenRecordSet, const CStdString& strCloseRecordSet,
493                          const CStdString& strOpenRecord, const CStdString& strCloseRecord, const CStdString& strOpenField, const CStdString& strCloseField, CStdString& strResult);
494   bool ArbitraryExec(const CStdString& strExec);
495
496   // general browsing
497   bool GetGenresNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
498   bool GetCountriesNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
499   bool GetStudiosNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
500   bool GetYearsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
501   bool GetActorsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
502   bool GetDirectorsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
503   bool GetWritersNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
504   bool GetSetsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1, const CStdString &where = "");
505   bool GetMusicVideoAlbumsNav(const CStdString& strBaseDir, CFileItemList& items, int idArtist);
506
507   bool GetMoviesNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idStudio=-1, int idCountry=-1, int idSet=-1);
508   bool GetTvShowsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idStudio=-1);
509   bool GetSeasonsNav(const CStdString& strBaseDir, CFileItemList& items, int idActor=-1, int idDirector=-1, int idGenre=-1, int idYear=-1, int idShow=-1);
510   bool GetEpisodesNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idShow=-1, int idSeason=-1);
511   bool GetMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idArtist=-1, int idDirector=-1, int idStudio=-1, int idAlbum=-1);
512
513   bool GetRecentlyAddedMoviesNav(const CStdString& strBaseDir, CFileItemList& items);
514   bool GetRecentlyAddedEpisodesNav(const CStdString& strBaseDir, CFileItemList& items);
515   bool GetRecentlyAddedMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items);
516
517   bool HasContent();
518   bool HasContent(VIDEODB_CONTENT_TYPE type);
519   bool HasSets() const;
520
521   void CleanDatabase(VIDEO::IVideoInfoScannerObserver* pObserver=NULL, const std::vector<int>* paths=NULL);
522
523   /*! \brief Add a file to the database, if necessary
524    If the file is already in the database, we simply return it's id.
525    \param url - full path of the file to add.
526    \return id of the file, -1 if it could not be added.
527    */
528   int AddFile(const CStdString& url);
529
530   /*! \brief Add a file to the database, if necessary
531    Works for both videodb:// items and normal fileitems
532    \param item CFileItem to add.
533    \return id of the file, -1 if it could not be added.
534    */
535   int AddFile(const CFileItem& item);
536
537   void ExportToXML(const CStdString &path, bool singleFiles = false, bool images=false, bool actorThumbs=false, bool overwrite=false);
538   bool ExportSkipEntry(const CStdString &nfoFile);
539   void ExportActorThumbs(const CStdString &path, const CVideoInfoTag& tag, bool singleFiles, bool overwrite=false);
540   void ImportFromXML(const CStdString &path);
541   void DumpToDummyFiles(const CStdString &path);
542   CStdString GetCachedThumb(const CFileItem& item) const;
543
544   // smart playlists and main retrieval work in these functions
545   bool GetMoviesByWhere(const CStdString& strBaseDir, const CStdString &where, const CStdString &order, CFileItemList& items, bool fetchSets = false);
546   bool GetTvShowsByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items);
547   bool GetEpisodesByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items, bool appendFullShowPath = true);
548   bool GetMusicVideosByWhere(const CStdString &baseDir, const CStdString &whereClause, CFileItemList& items, bool checkLocks = true);
549
550   // partymode
551   int GetMusicVideoCount(const CStdString& strWhere);
552   unsigned int GetMusicVideoIDs(const CStdString& strWhere, std::vector<std::pair<int,int> > &songIDs);
553   bool GetRandomMusicVideo(CFileItem* item, int& idSong, const CStdString& strWhere);
554
555   static void VideoContentTypeToString(VIDEODB_CONTENT_TYPE type, CStdString& out)
556   {
557     switch (type)
558     {
559     case VIDEODB_CONTENT_MOVIES:
560       out = "movie";
561       break;
562     case VIDEODB_CONTENT_TVSHOWS:
563       out = "tvshow";
564       break;
565     case VIDEODB_CONTENT_EPISODES:
566       out = "episode";
567       break;
568     case VIDEODB_CONTENT_MUSICVIDEOS:
569       out = "musicvideo";
570       break;
571     default:
572       break;
573     }
574   }
575
576 protected:
577   int GetMovieId(const CStdString& strFilenameAndPath);
578   int GetMusicVideoId(const CStdString& strFilenameAndPath);
579
580   /*! \brief Get the id of this fileitem
581    Works for both videodb:// items and normal fileitems
582    \param item CFileItem to grab the fileid of
583    \return id of the file, -1 if it is not in the db.
584    */
585   int GetFileId(const CFileItem &item);
586
587   /*! \brief Get the id of a file from path
588    \param url full path to the file
589    \return id of the file, -1 if it is not in the db.
590    */
591   int GetFileId(const CStdString& url);
592
593   int AddPath(const CStdString& strPath);
594   int AddToTable(const CStdString& table, const CStdString& firstField, const CStdString& secondField, const CStdString& value);
595   int AddGenre(const CStdString& strGenre1);
596   int AddActor(const CStdString& strActor, const CStdString& strThumb);
597   int AddCountry(const CStdString& strCountry);
598   int AddSet(const CStdString& strSet);
599   int AddStudio(const CStdString& strStudio1);
600
601   int AddTvShow(const CStdString& strPath);
602   int AddMusicVideo(const CStdString& strFilenameAndPath);
603
604   // link functions - these two do all the work
605   void AddLinkToActor(const char *table, int actorID, const char *secondField, int secondID, const CStdString &role);
606   void AddToLinkTable(const char *table, const char *firstField, int firstID, const char *secondField, int secondID);
607
608   void AddSetToMovie(int idMovie, int idSet);
609
610   void AddActorToMovie(int idMovie, int idActor, const CStdString& strRole);
611   void AddActorToTvShow(int idTvShow, int idActor, const CStdString& strRole);
612   void AddActorToEpisode(int idEpisode, int idActor, const CStdString& strRole);
613   void AddArtistToMusicVideo(int lMVideo, int idArtist);
614
615   void AddDirectorToMovie(int idMovie, int idDirector);
616   void AddDirectorToTvShow(int idTvShow, int idDirector);
617   void AddDirectorToEpisode(int idEpisode, int idDirector);
618   void AddDirectorToMusicVideo(int lMVideo, int idDirector);
619   void AddWriterToEpisode(int idEpisode, int idWriter);
620   void AddWriterToMovie(int idMovie, int idWriter);
621
622   void AddGenreToMovie(int idMovie, int idGenre);
623   void AddGenreToTvShow(int idTvShow, int idGenre);
624   void AddGenreToMusicVideo(int idMVideo, int idGenre);
625
626   void AddStudioToMovie(int idMovie, int idStudio);
627   void AddStudioToTvShow(int idTvShow, int idStudio);
628   void AddStudioToMusicVideo(int idMVideo, int idStudio);
629
630   void AddCountryToMovie(int idMovie, int idCountry);
631
632   void AddGenreAndDirectorsAndStudios(const CVideoInfoTag& details, std::vector<int>& vecDirectors, std::vector<int>& vecGenres, std::vector<int>& vecStudios);
633
634   void DeleteStreamDetails(int idFile);
635   CVideoInfoTag GetDetailsByTypeAndId(VIDEODB_CONTENT_TYPE type, int id);
636   CVideoInfoTag GetDetailsForMovie(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
637   CVideoInfoTag GetDetailsForTvShow(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
638   CVideoInfoTag GetDetailsForEpisode(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
639   CVideoInfoTag GetDetailsForMusicVideo(std::auto_ptr<dbiplus::Dataset> &pDS);
640   void GetCommonDetails(std::auto_ptr<dbiplus::Dataset> &pDS, CVideoInfoTag &details);
641   bool GetPeopleNav(const CStdString& strBaseDir, CFileItemList& items, const CStdString& type, int idContent=-1);
642   bool GetNavCommon(const CStdString& strBaseDir, CFileItemList& items, const CStdString& type, int idContent=-1);
643
644   void GetDetailsFromDB(std::auto_ptr<dbiplus::Dataset> &pDS, int min, int max, const SDbTableOffsets *offsets, CVideoInfoTag &details, int idxOffset = 2);
645   CStdString GetValueString(const CVideoInfoTag &details, int min, int max, const SDbTableOffsets *offsets) const;
646
647 private:
648   virtual bool CreateTables();
649   virtual bool UpdateOldVersion(int version);
650
651   /*! \brief Run a query on the main dataset and return the number of rows
652    If no rows are found we close the dataset and return 0.
653    \param sql the sql query to run
654    \return the number of rows, -1 for an error.
655    */
656   int RunQuery(const CStdString &sql);
657
658   /*! \brief Update routine for base path of videos
659    Only required for videodb version < 44
660    \param table the table to update
661    \param id the primary id in the given table
662    \param column the basepath column to update
663    \param shows whether we're fetching shows (defaults to false)
664    */
665   void UpdateBasePath(const char *table, const char *id, int column, bool shows = false);
666
667   virtual int GetMinVersion() const { return 46; };
668   const char *GetBaseDBName() const { return "MyVideos"; };
669
670   void ConstructPath(CStdString& strDest, const CStdString& strPath, const CStdString& strFileName);
671   void SplitPath(const CStdString& strFileNameAndPath, CStdString& strPath, CStdString& strFileName);
672   void InvalidatePathHash(const CStdString& strPath);
673   void DeleteThumbForItem(const CStdString& strPath, bool bFolder, int idEpisode = -1);
674
675   bool GetStackedTvShowList(int idShow, CStdString& strIn);
676   void Stack(CFileItemList& items, VIDEODB_CONTENT_TYPE type, bool maintainSortOrder = false);
677
678   /*! \brief Get a safe filename from a given string
679    \param dir directory to use for the file
680    \param name movie, show name, or actor to get a safe filename for
681    \return safe filename based on this title
682    */
683   CStdString GetSafeFile(const CStdString &dir, const CStdString &name) const;
684
685   void AnnounceRemove(std::string content, int id);
686   void AnnounceUpdate(std::string content, int id);
687 };