added async resume point retrieving by thumbloader
[xbmc:paulepanters-xbmc.git] / 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 24
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_PARENTPATHID = 23,
122   VIDEODB_ID_MAX
123 } VIDEODB_IDS;
124
125 const struct SDbTableOffsets
126 {
127   int type;
128   size_t offset;
129 } DbMovieOffsets[] =
130 {
131   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTitle) },
132   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlot) },
133   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlotOutline) },
134   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTagLine) },
135   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strVotes) },
136   { VIDEODB_TYPE_FLOAT, my_offsetof(CVideoInfoTag,m_fRating) },
137   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strWritingCredits) },
138   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iYear) },
139   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_xml) },
140   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strIMDBNumber) },
141   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strSortTitle) },
142   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strRuntime) },
143   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strMPAARating) },
144   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iTop250) },
145   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strGenre) },
146   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strDirector) },
147   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strOriginalTitle) },
148   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_spoof) },
149   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strStudio) },
150   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTrailer) },
151   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_fanart.m_xml) },
152   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strCountry) },
153   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_basePath) },
154   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_parentPathID) }
155 };
156
157 typedef enum // this enum MUST match the offset struct further down!! and make sure to keep min and max at -1 and sizeof(offsets)
158 {
159   VIDEODB_ID_TV_MIN = -1,
160   VIDEODB_ID_TV_TITLE = 0,
161   VIDEODB_ID_TV_PLOT = 1,
162   VIDEODB_ID_TV_STATUS = 2,
163   VIDEODB_ID_TV_VOTES = 3,
164   VIDEODB_ID_TV_RATING = 4,
165   VIDEODB_ID_TV_PREMIERED = 5,
166   VIDEODB_ID_TV_THUMBURL = 6,
167   VIDEODB_ID_TV_THUMBURL_SPOOF = 7,
168   VIDEODB_ID_TV_GENRE = 8,
169   VIDEODB_ID_TV_ORIGINALTITLE = 9,
170   VIDEODB_ID_TV_EPISODEGUIDE = 10,
171   VIDEODB_ID_TV_FANART = 11,
172   VIDEODB_ID_TV_IDENT = 12,
173   VIDEODB_ID_TV_MPAA = 13,
174   VIDEODB_ID_TV_STUDIOS = 14,
175   VIDEODB_ID_TV_SORTTITLE = 15,
176   VIDEODB_ID_TV_BASEPATH = 16,
177   VIDEODB_ID_TV_PARENTPATHID = 17,
178   VIDEODB_ID_TV_MAX
179 } VIDEODB_TV_IDS;
180
181 const struct SDbTableOffsets DbTvShowOffsets[] =
182 {
183   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTitle) },
184   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlot) },
185   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strStatus) },
186   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strVotes) },
187   { VIDEODB_TYPE_FLOAT, my_offsetof(CVideoInfoTag,m_fRating) },
188   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPremiered) },
189   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_xml) },
190   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_spoof) },
191   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strGenre) },
192   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strOriginalTitle)},
193   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strEpisodeGuide)},
194   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_fanart.m_xml)},
195   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strIMDBNumber)},
196   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strMPAARating)},
197   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strStudio)},
198   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strSortTitle)},
199   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_basePath) },
200   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_parentPathID) }
201 };
202
203 typedef enum // this enum MUST match the offset struct further down!! and make sure to keep min and max at -1 and sizeof(offsets)
204 {
205   VIDEODB_ID_EPISODE_MIN = -1,
206   VIDEODB_ID_EPISODE_TITLE = 0,
207   VIDEODB_ID_EPISODE_PLOT = 1,
208   VIDEODB_ID_EPISODE_VOTES = 2,
209   VIDEODB_ID_EPISODE_RATING = 3,
210   VIDEODB_ID_EPISODE_CREDITS = 4,
211   VIDEODB_ID_EPISODE_AIRED = 5,
212   VIDEODB_ID_EPISODE_THUMBURL = 6,
213   VIDEODB_ID_EPISODE_THUMBURL_SPOOF = 7,
214   VIDEODB_ID_EPISODE_PLAYCOUNT = 8, // unused - feel free to repurpose
215   VIDEODB_ID_EPISODE_RUNTIME = 9,
216   VIDEODB_ID_EPISODE_DIRECTOR = 10,
217   VIDEODB_ID_EPISODE_IDENT = 11,
218   VIDEODB_ID_EPISODE_SEASON = 12,
219   VIDEODB_ID_EPISODE_EPISODE = 13,
220   VIDEODB_ID_EPISODE_ORIGINALTITLE = 14,
221   VIDEODB_ID_EPISODE_SORTSEASON = 15,
222   VIDEODB_ID_EPISODE_SORTEPISODE = 16,
223   VIDEODB_ID_EPISODE_BOOKMARK = 17,
224   VIDEODB_ID_EPISODE_BASEPATH = 18,
225   VIDEODB_ID_EPISODE_PARENTPATHID = 19,
226   VIDEODB_ID_EPISODE_MAX
227 } VIDEODB_EPISODE_IDS;
228
229 const struct SDbTableOffsets DbEpisodeOffsets[] =
230 {
231   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strTitle) },
232   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlot) },
233   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strVotes) },
234   { VIDEODB_TYPE_FLOAT, my_offsetof(CVideoInfoTag,m_fRating) },
235   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strWritingCredits) },
236   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strFirstAired) },
237   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_xml) },
238   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_spoof) },
239   { VIDEODB_TYPE_COUNT, my_offsetof(CVideoInfoTag,m_playCount) }, // unused
240   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strRuntime) },
241   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strDirector) },
242   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strProductionCode) },
243   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iSeason) },
244   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iEpisode) },
245   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strOriginalTitle)},
246   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iSpecialSortSeason) },
247   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iSpecialSortEpisode) },
248   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iBookmarkId) },
249   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_basePath) },
250   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_parentPathID) }
251 };
252
253 typedef enum // this enum MUST match the offset struct further down!! and make sure to keep min and max at -1 and sizeof(offsets)
254 {
255   VIDEODB_ID_MUSICVIDEO_MIN = -1,
256   VIDEODB_ID_MUSICVIDEO_TITLE = 0,
257   VIDEODB_ID_MUSICVIDEO_THUMBURL = 1,
258   VIDEODB_ID_MUSICVIDEO_THUMBURL_SPOOF = 2,
259   VIDEODB_ID_MUSICVIDEO_PLAYCOUNT = 3, // unused - feel free to repurpose
260   VIDEODB_ID_MUSICVIDEO_RUNTIME = 4,
261   VIDEODB_ID_MUSICVIDEO_DIRECTOR = 5,
262   VIDEODB_ID_MUSICVIDEO_STUDIOS = 6,
263   VIDEODB_ID_MUSICVIDEO_YEAR = 7,
264   VIDEODB_ID_MUSICVIDEO_PLOT = 8,
265   VIDEODB_ID_MUSICVIDEO_ALBUM = 9,
266   VIDEODB_ID_MUSICVIDEO_ARTIST = 10,
267   VIDEODB_ID_MUSICVIDEO_GENRE = 11,
268   VIDEODB_ID_MUSICVIDEO_TRACK = 12,
269   VIDEODB_ID_MUSICVIDEO_BASEPATH = 13,
270   VIDEODB_ID_MUSICVIDEO_PARENTPATHID = 14,
271   VIDEODB_ID_MUSICVIDEO_MAX
272 } VIDEODB_MUSICVIDEO_IDS;
273
274 const struct SDbTableOffsets DbMusicVideoOffsets[] =
275 {
276   { VIDEODB_TYPE_STRING, my_offsetof(class CVideoInfoTag,m_strTitle) },
277   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_xml) },
278   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPictureURL.m_spoof) },
279   { VIDEODB_TYPE_COUNT, my_offsetof(CVideoInfoTag,m_playCount) }, // unused
280   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strRuntime) },
281   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strDirector) },
282   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strStudio) },
283   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iYear) },
284   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strPlot) },
285   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strAlbum) },
286   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strArtist) },
287   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_strGenre) },
288   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_iTrack) },
289   { VIDEODB_TYPE_STRING, my_offsetof(CVideoInfoTag,m_basePath) },
290   { VIDEODB_TYPE_INT, my_offsetof(CVideoInfoTag,m_parentPathID) }
291 };
292
293 #define COMPARE_PERCENTAGE     0.90f // 90%
294 #define COMPARE_PERCENTAGE_MIN 0.50f // 50%
295
296 class CVideoDatabase : public CDatabase
297 {
298 public:
299
300   class CActor    // used for actor retrieval for non-master users
301   {
302   public:
303     CStdString name;
304     CStdString thumb;
305     int playcount;
306   };
307
308   class CSeason   // used for season retrieval for non-master users
309   {
310   public:
311     CStdString path;
312     CStdString genre;
313     int numEpisodes;
314     int numWatched;
315   };
316
317   CVideoDatabase(void);
318   virtual ~CVideoDatabase(void);
319
320   virtual bool Open();
321   virtual bool CommitTransaction();
322
323   int AddMovie(const CStdString& strFilenameAndPath);
324   int AddEpisode(int idShow, const CStdString& strFilenameAndPath);
325
326   // editing functions
327   /*! \brief Set the playcount of an item
328    Sets the playcount and last played date to a given value
329    \param item CFileItem to set the playcount for
330    \param count The playcount to set.
331    \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).
332    \sa GetPlayCount, IncrementPlayCount, UpdateLastPlayed
333    */
334   void SetPlayCount(const CFileItem &item, int count, const CStdString &date = "");
335
336   /*! \brief Increment the playcount of an item
337    Increments the playcount and updates the last played date
338    \param item CFileItem to increment the playcount for
339    \sa GetPlayCount, SetPlayCount, GetPlayCounts
340    */
341   void IncrementPlayCount(const CFileItem &item);
342
343   /*! \brief Get the playcount of an item
344    \param item CFileItem to get the playcount for
345    \return the playcount of the item, or -1 on error
346    \sa SetPlayCount, IncrementPlayCount, GetPlayCounts
347    */
348   int GetPlayCount(const CFileItem &item);
349
350   /*! \brief Update the last played time of an item
351    Updates the last played date
352    \param item CFileItem to update the last played time for
353    \sa GetPlayCount, SetPlayCount, IncrementPlayCount, GetPlayCounts
354    */
355   void UpdateLastPlayed(const CFileItem &item);
356
357   /*! \brief Get the playcount of a list of items
358    \param path the path to fetch videos from
359    \param items CFileItemList to fetch the playcounts for
360    \sa GetPlayCount, SetPlayCount, IncrementPlayCount
361    */
362   bool GetPlayCounts(const CStdString &path, CFileItemList &items);
363
364   void UpdateMovieTitle(int idMovie, const CStdString& strNewMovieTitle, VIDEODB_CONTENT_TYPE iType=VIDEODB_CONTENT_MOVIES);
365
366   bool HasMovieInfo(const CStdString& strFilenameAndPath);
367   bool HasTvShowInfo(const CStdString& strFilenameAndPath);
368   bool HasEpisodeInfo(const CStdString& strFilenameAndPath);
369   bool HasMusicVideoInfo(const CStdString& strFilenameAndPath);
370
371   void GetFilePathById(int idMovie, CStdString &filePath, VIDEODB_CONTENT_TYPE iType);
372   CStdString GetGenreById(int id);
373   CStdString GetCountryById(int id);
374   CStdString GetSetById(int id);
375   CStdString GetPersonById(int id);
376   CStdString GetStudioById(int id);
377   CStdString GetTvShowTitleById(int id);
378   CStdString GetMusicVideoAlbumById(int id);
379   int GetTvShowForEpisode(int idEpisode);
380
381   bool LoadVideoInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details);
382   void GetMovieInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idMovie = -1);
383   void GetTvShowInfo(const CStdString& strPath, CVideoInfoTag& details, int idTvShow = -1);
384   bool GetEpisodeInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idEpisode = -1);
385   void GetMusicVideoInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idMVideo=-1);
386   void GetSetInfo(int idSet, CVideoInfoTag& details);
387
388   int GetPathId(const CStdString& strPath);
389   int GetTvShowId(const CStdString& strPath);
390   int GetEpisodeId(const CStdString& strFilenameAndPath, int idEpisode=-1, int idSeason=-1); // idEpisode, idSeason are used for multipart episodes as hints
391
392   void GetEpisodesByFile(const CStdString& strFilenameAndPath, std::vector<CVideoInfoTag>& episodes);
393
394   int SetDetailsForMovie(const CStdString& strFilenameAndPath, const CVideoInfoTag& details);
395   int SetDetailsForTvShow(const CStdString& strPath, const CVideoInfoTag& details);
396   int SetDetailsForEpisode(const CStdString& strFilenameAndPath, const CVideoInfoTag& details, int idShow, int idEpisode=-1);
397   int SetDetailsForMusicVideo(const CStdString& strFilenameAndPath, const CVideoInfoTag& details);
398   void SetStreamDetailsForFile(const CStreamDetails& details, const CStdString &strFileNameAndPath);
399   void SetStreamDetailsForFileId(const CStreamDetails& details, int idFile);
400   void SetDetail(const CStdString& strDetail, int id, int field, VIDEODB_CONTENT_TYPE type);
401
402   void DeleteMovie(const CStdString& strFilenameAndPath, bool bKeepId = false, bool bKeepThumb = false);
403   void DeleteTvShow(const CStdString& strPath, bool bKeepId = false, bool bKeepThumb = false);
404   void DeleteEpisode(const CStdString& strFilenameAndPath, int idEpisode = -1, bool bKeepId = false, bool bKeepThumb = false);
405   void DeleteMusicVideo(const CStdString& strFilenameAndPath, bool bKeepId = false, bool bKeepThumb = false);
406   void DeleteDetailsForTvShow(const CStdString& strPath);
407   void RemoveContentForPath(const CStdString& strPath,CGUIDialogProgress *progress = NULL);
408   void UpdateFanart(const CFileItem &item, VIDEODB_CONTENT_TYPE type);
409   void DeleteSet(int idSet);
410
411   // per-file video settings
412   bool GetVideoSettings(const CStdString &strFilenameAndPath, CVideoSettings &settings);
413   void SetVideoSettings(const CStdString &strFilenameAndPath, const CVideoSettings &settings);
414   void EraseVideoSettings();
415
416   bool GetStackTimes(const CStdString &filePath, std::vector<int> &times);
417   void SetStackTimes(const CStdString &filePath, std::vector<int> &times);
418
419   void GetBookMarksForFile(const CStdString& strFilenameAndPath, VECBOOKMARKS& bookmarks, CBookmark::EType type = CBookmark::STANDARD, bool bAppend=false);
420   void AddBookMarkToFile(const CStdString& strFilenameAndPath, const CBookmark &bookmark, CBookmark::EType type = CBookmark::STANDARD);
421   bool GetResumeBookMark(const CStdString& strFilenameAndPath, CBookmark &bookmark);
422   void DeleteResumeBookMark(const CStdString &strFilenameAndPath);
423   void ClearBookMarkOfFile(const CStdString& strFilenameAndPath, CBookmark& bookmark, CBookmark::EType type = CBookmark::STANDARD);
424   void ClearBookMarksOfFile(const CStdString& strFilenameAndPath, CBookmark::EType type = CBookmark::STANDARD);
425   bool GetBookMarkForEpisode(const CVideoInfoTag& tag, CBookmark& bookmark);
426   void AddBookMarkForEpisode(const CVideoInfoTag& tag, const CBookmark& bookmark);
427   void DeleteBookMarkForEpisode(const CVideoInfoTag& tag);
428   bool GetResumePoint(CVideoInfoTag& tag) const;
429
430   // scraper settings
431   void SetScraperForPath(const CStdString& filePath, const ADDON::ScraperPtr& info, const VIDEO::SScanSettings& settings);
432   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath);
433   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath, VIDEO::SScanSettings& settings);
434
435   /*! \brief Retrieve the scraper and settings we should use for the specified path
436    If the scraper is not set on this particular path, we'll recursively check parent folders.
437    \param strPath path to start searching in.
438    \param settings [out] scan settings for this folder.
439    \param foundDirectly [out] true if a scraper was found directly for strPath, false if it was in a parent path.
440    \return A ScraperPtr containing the scraper information. Returns NULL if a trivial (Content == CONTENT_NONE)
441            scraper or no scraper is found.
442    */
443   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath, VIDEO::SScanSettings& settings, bool& foundDirectly);
444
445   /*! \brief Retrieve the content type of videos in the given path
446    If content is set on the folder, we return the given content type, except in the case of tvshows,
447    where we first check for whether we have episodes directly in the path (thus return episodes) or whether
448    we've found a scraper directly (shows).  Any folders inbetween are treated as seasons (regardless of whether
449    they actually are seasons). Note that any subfolders in movies will be treated as movies.
450    \param strPath path to start searching in.
451    \return A content type string for the current path.
452    */
453   CStdString GetContentForPath(const CStdString& strPath);
454
455   /*! \brief Get videos of the given content type from the given path
456    \param content the content type to fetch.
457    \param path the path to fetch videos from.
458    \param items the returned items
459    \return true if items are found, false otherwise.
460    */
461   bool GetItemsForPath(const CStdString &content, const CStdString &path, CFileItemList &items);
462
463   /*! \brief Check whether a given scraper is in use.
464    \param scraperID the scraper to check for.
465    \return true if the scraper is in use, false otherwise.
466    */
467   bool ScraperInUse(const CStdString &scraperID) const;
468   
469   // scanning hashes and paths scanned
470   bool SetPathHash(const CStdString &path, const CStdString &hash);
471   bool GetPathHash(const CStdString &path, CStdString &hash);
472   bool GetPaths(std::set<CStdString> &paths);
473   bool GetPathsForTvShow(int idShow, std::vector<int>& paths);
474
475   /*! \brief retrieve subpaths of a given path.  Assumes a heirarchical folder structure
476    \param basepath the root path to retrieve subpaths for
477    \param subpaths the returned subpaths
478    \return true if we successfully retrieve subpaths (may be zero), false on error
479    */
480   bool GetSubPaths(const CStdString& basepath, std::vector<int>& subpaths);
481
482   // for music + musicvideo linkups - if no album and title given it will return the artist id, else the id of the matching video
483   int GetMatchingMusicVideo(const CStdString& strArtist, const CStdString& strAlbum = "", const CStdString& strTitle = "");
484
485   // searching functions
486   void GetMoviesByActor(const CStdString& strActor, CFileItemList& items);
487   void GetTvShowsByActor(const CStdString& strActor, CFileItemList& items);
488   void GetEpisodesByActor(const CStdString& strActor, CFileItemList& items);
489
490   void GetMusicVideosByArtist(const CStdString& strArtist, CFileItemList& items);
491   void GetMusicVideosByAlbum(const CStdString& strAlbum, CFileItemList& items);
492
493   void GetMovieGenresByName(const CStdString& strSearch, CFileItemList& items);
494   void GetTvShowGenresByName(const CStdString& strSearch, CFileItemList& items);
495   void GetMusicVideoGenresByName(const CStdString& strSearch, CFileItemList& items);
496
497   void GetMovieCountriesByName(const CStdString& strSearch, CFileItemList& items);
498
499   void GetMusicVideoAlbumsByName(const CStdString& strSearch, CFileItemList& items);
500
501   void GetMovieActorsByName(const CStdString& strSearch, CFileItemList& items);
502   void GetTvShowsActorsByName(const CStdString& strSearch, CFileItemList& items);
503   void GetMusicVideoArtistsByName(const CStdString& strSearch, CFileItemList& items);
504
505   void GetMovieDirectorsByName(const CStdString& strSearch, CFileItemList& items);
506   void GetTvShowsDirectorsByName(const CStdString& strSearch, CFileItemList& items);
507   void GetMusicVideoDirectorsByName(const CStdString& strSearch, CFileItemList& items);
508
509   void GetMoviesByName(const CStdString& strSearch, CFileItemList& items);
510   void GetTvShowsByName(const CStdString& strSearch, CFileItemList& items);
511   void GetEpisodesByName(const CStdString& strSearch, CFileItemList& items);
512   void GetMusicVideosByName(const CStdString& strSearch, CFileItemList& items);
513
514   void GetEpisodesByPlot(const CStdString& strSearch, CFileItemList& items);
515   void GetMoviesByPlot(const CStdString& strSearch, CFileItemList& items);
516
517   bool LinkMovieToTvshow(int idMovie, int idShow, bool bRemove);
518   bool IsLinkedToTvshow(int idMovie);
519   bool GetLinksToTvShow(int idMovie, std::vector<int>& ids);
520
521   bool GetArbitraryQuery(const CStdString& strQuery, const CStdString& strOpenRecordSet, const CStdString& strCloseRecordSet,
522                          const CStdString& strOpenRecord, const CStdString& strCloseRecord, const CStdString& strOpenField, const CStdString& strCloseField, CStdString& strResult);
523   bool ArbitraryExec(const CStdString& strExec);
524
525   // general browsing
526   bool GetGenresNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
527   bool GetCountriesNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
528   bool GetStudiosNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
529   bool GetYearsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
530   bool GetActorsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
531   bool GetDirectorsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
532   bool GetWritersNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
533   bool GetSetsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1, const CStdString &where = "");
534   bool GetMusicVideoAlbumsNav(const CStdString& strBaseDir, CFileItemList& items, int idArtist);
535
536   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);
537   bool GetTvShowsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idStudio=-1);
538   bool GetSeasonsNav(const CStdString& strBaseDir, CFileItemList& items, int idActor=-1, int idDirector=-1, int idGenre=-1, int idYear=-1, int idShow=-1);
539   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);
540   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);
541   
542   bool GetRecentlyAddedMoviesNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit=0);
543   bool GetRecentlyAddedEpisodesNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit=0);
544   bool GetRecentlyAddedMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit=0);
545
546   bool HasContent();
547   bool HasContent(VIDEODB_CONTENT_TYPE type);
548   bool HasSets() const;
549
550   void CleanDatabase(VIDEO::IVideoInfoScannerObserver* pObserver=NULL, const std::vector<int>* paths=NULL);
551
552   /*! \brief Add a file to the database, if necessary
553    If the file is already in the database, we simply return its id.
554    \param url - full path of the file to add.
555    \return id of the file, -1 if it could not be added.
556    */
557   int AddFile(const CStdString& url);
558
559   /*! \brief Add a file to the database, if necessary
560    Works for both videodb:// items and normal fileitems
561    \param item CFileItem to add.
562    \return id of the file, -1 if it could not be added.
563    */
564   int AddFile(const CFileItem& item);
565
566   /*! \brief Add a path to the database, if necessary
567    If the path is already in the database, we simply return its id.
568    \param strPath the path to add
569    \return id of the file, -1 if it could not be added.
570    */
571   int AddPath(const CStdString& strPath);
572
573   void ExportToXML(const CStdString &path, bool singleFiles = false, bool images=false, bool actorThumbs=false, bool overwrite=false);
574   bool ExportSkipEntry(const CStdString &nfoFile);
575   void ExportActorThumbs(const CStdString &path, const CVideoInfoTag& tag, bool singleFiles, bool overwrite=false);
576   void ImportFromXML(const CStdString &path);
577   void DumpToDummyFiles(const CStdString &path);
578   CStdString GetCachedThumb(const CFileItem& item) const;
579
580   // smart playlists and main retrieval work in these functions
581   bool GetMoviesByWhere(const CStdString& strBaseDir, const CStdString &where, const CStdString &order, CFileItemList& items, bool fetchSets = false);
582   bool GetTvShowsByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items);
583   bool GetEpisodesByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items, bool appendFullShowPath = true);
584   bool GetMusicVideosByWhere(const CStdString &baseDir, const CStdString &whereClause, CFileItemList& items, bool checkLocks = true);
585
586   // partymode
587   int GetMusicVideoCount(const CStdString& strWhere);
588   unsigned int GetMusicVideoIDs(const CStdString& strWhere, std::vector<std::pair<int,int> > &songIDs);
589   bool GetRandomMusicVideo(CFileItem* item, int& idSong, const CStdString& strWhere);
590
591   static void VideoContentTypeToString(VIDEODB_CONTENT_TYPE type, CStdString& out)
592   {
593     switch (type)
594     {
595     case VIDEODB_CONTENT_MOVIES:
596       out = "movie";
597       break;
598     case VIDEODB_CONTENT_TVSHOWS:
599       out = "tvshow";
600       break;
601     case VIDEODB_CONTENT_EPISODES:
602       out = "episode";
603       break;
604     case VIDEODB_CONTENT_MUSICVIDEOS:
605       out = "musicvideo";
606       break;
607     default:
608       break;
609     }
610   }
611
612 protected:
613   int GetMovieId(const CStdString& strFilenameAndPath);
614   int GetMusicVideoId(const CStdString& strFilenameAndPath);
615
616   /*! \brief Get the id of this fileitem
617    Works for both videodb:// items and normal fileitems
618    \param item CFileItem to grab the fileid of
619    \return id of the file, -1 if it is not in the db.
620    */
621   int GetFileId(const CFileItem &item);
622
623   /*! \brief Get the id of a file from path
624    \param url full path to the file
625    \return id of the file, -1 if it is not in the db.
626    */
627   int GetFileId(const CStdString& url);
628
629   int AddToTable(const CStdString& table, const CStdString& firstField, const CStdString& secondField, const CStdString& value);
630   int AddGenre(const CStdString& strGenre1);
631   int AddActor(const CStdString& strActor, const CStdString& strThumb);
632   int AddCountry(const CStdString& strCountry);
633   int AddSet(const CStdString& strSet);
634   int AddStudio(const CStdString& strStudio1);
635
636   int AddTvShow(const CStdString& strPath);
637   int AddMusicVideo(const CStdString& strFilenameAndPath);
638
639   // link functions - these two do all the work
640   void AddLinkToActor(const char *table, int actorID, const char *secondField, int secondID, const CStdString &role, int order);
641   void AddToLinkTable(const char *table, const char *firstField, int firstID, const char *secondField, int secondID);
642
643   void AddSetToMovie(int idMovie, int idSet);
644
645   void AddActorToMovie(int idMovie, int idActor, const CStdString& strRole, int order);
646   void AddActorToTvShow(int idTvShow, int idActor, const CStdString& strRole, int order);
647   void AddActorToEpisode(int idEpisode, int idActor, const CStdString& strRole, int order);
648   void AddArtistToMusicVideo(int lMVideo, int idArtist);
649
650   void AddDirectorToMovie(int idMovie, int idDirector);
651   void AddDirectorToTvShow(int idTvShow, int idDirector);
652   void AddDirectorToEpisode(int idEpisode, int idDirector);
653   void AddDirectorToMusicVideo(int lMVideo, int idDirector);
654   void AddWriterToEpisode(int idEpisode, int idWriter);
655   void AddWriterToMovie(int idMovie, int idWriter);
656
657   void AddGenreToMovie(int idMovie, int idGenre);
658   void AddGenreToTvShow(int idTvShow, int idGenre);
659   void AddGenreToMusicVideo(int idMVideo, int idGenre);
660
661   void AddStudioToMovie(int idMovie, int idStudio);
662   void AddStudioToTvShow(int idTvShow, int idStudio);
663   void AddStudioToMusicVideo(int idMVideo, int idStudio);
664
665   void AddCountryToMovie(int idMovie, int idCountry);
666
667   void AddGenreAndDirectorsAndStudios(const CVideoInfoTag& details, std::vector<int>& vecDirectors, std::vector<int>& vecGenres, std::vector<int>& vecStudios);
668
669   void DeleteStreamDetails(int idFile);
670   CVideoInfoTag GetDetailsByTypeAndId(VIDEODB_CONTENT_TYPE type, int id);
671   CVideoInfoTag GetDetailsForMovie(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
672   CVideoInfoTag GetDetailsForTvShow(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
673   CVideoInfoTag GetDetailsForEpisode(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
674   CVideoInfoTag GetDetailsForMusicVideo(std::auto_ptr<dbiplus::Dataset> &pDS);
675   void GetCommonDetails(std::auto_ptr<dbiplus::Dataset> &pDS, CVideoInfoTag &details);
676   bool GetPeopleNav(const CStdString& strBaseDir, CFileItemList& items, const CStdString& type, int idContent=-1);
677   bool GetNavCommon(const CStdString& strBaseDir, CFileItemList& items, const CStdString& type, int idContent=-1);
678
679   void GetDetailsFromDB(std::auto_ptr<dbiplus::Dataset> &pDS, int min, int max, const SDbTableOffsets *offsets, CVideoInfoTag &details, int idxOffset = 2);
680   CStdString GetValueString(const CVideoInfoTag &details, int min, int max, const SDbTableOffsets *offsets) const;
681   bool GetStreamDetails(CVideoInfoTag& tag) const;
682
683 private:
684   virtual bool CreateTables();
685   virtual bool UpdateOldVersion(int version);
686
687   /*! \brief (Re)Create the generic database views for movies, tvshows,
688      episodes and music videos
689    */
690   void CreateViews();
691
692   /*! \brief Run a query on the main dataset and return the number of rows
693    If no rows are found we close the dataset and return 0.
694    \param sql the sql query to run
695    \return the number of rows, -1 for an error.
696    */
697   int RunQuery(const CStdString &sql);
698
699   /*! \brief Update routine for base path of videos
700    Only required for videodb version < 44
701    \param table the table to update
702    \param id the primary id in the given table
703    \param column the basepath column to update
704    \param shows whether we're fetching shows (defaults to false)
705    */
706   void UpdateBasePath(const char *table, const char *id, int column, bool shows = false);
707
708   /*! \brief Update routine for base path id of videos
709    Only required for videodb version < 52
710    \param table the table to update
711    \param id the primary id in the given table
712    \param column the column of the basepath
713    \param idColumn the column of the parent path id to update
714    */
715   void UpdateBasePathID(const char *table, const char *id, int column, int idColumn);
716
717   /*! \brief Determine whether the path is using lookup using folders
718    \param path the path to check
719    \param shows whether this path is from a tvshow (defaults to false)
720    */
721   bool LookupByFolders(const CStdString &path, bool shows = false);
722
723   virtual int GetMinVersion() const { return 54; };
724   virtual int GetExportVersion() const { return 1; };
725   const char *GetBaseDBName() const { return "MyVideos"; };
726
727   void ConstructPath(CStdString& strDest, const CStdString& strPath, const CStdString& strFileName);
728   void SplitPath(const CStdString& strFileNameAndPath, CStdString& strPath, CStdString& strFileName);
729   void InvalidatePathHash(const CStdString& strPath);
730   void DeleteThumbForItem(const CStdString& strPath, bool bFolder, int idEpisode = -1);
731
732   bool GetStackedTvShowList(int idShow, CStdString& strIn);
733   void Stack(CFileItemList& items, VIDEODB_CONTENT_TYPE type, bool maintainSortOrder = false);
734
735   /*! \brief Get a safe filename from a given string
736    \param dir directory to use for the file
737    \param name movie, show name, or actor to get a safe filename for
738    \return safe filename based on this title
739    */
740   CStdString GetSafeFile(const CStdString &dir, const CStdString &name) const;
741
742   void AnnounceRemove(std::string content, int id);
743   void AnnounceUpdate(std::string content, int id);
744 };