Merge pull request #116 from IronTetsubo/master
[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   CStdString GetGenreById(int id);
358   CStdString GetCountryById(int id);
359   CStdString GetSetById(int id);
360   CStdString GetPersonById(int id);
361   CStdString GetStudioById(int id);
362   CStdString GetTvShowTitleById(int id);
363   CStdString GetMusicVideoAlbumById(int id);
364   int GetTvShowForEpisode(int idEpisode);
365
366   bool LoadVideoInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details);
367   void GetMovieInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idMovie = -1);
368   void GetTvShowInfo(const CStdString& strPath, CVideoInfoTag& details, int idTvShow = -1);
369   bool GetEpisodeInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idEpisode = -1);
370   void GetMusicVideoInfo(const CStdString& strFilenameAndPath, CVideoInfoTag& details, int idMVideo=-1);
371   void GetSetInfo(int idSet, CVideoInfoTag& details);
372
373   int GetPathId(const CStdString& strPath);
374   int GetTvShowId(const CStdString& strPath);
375   int GetEpisodeId(const CStdString& strFilenameAndPath, int idEpisode=-1, int idSeason=-1); // idEpisode, idSeason are used for multipart episodes as hints
376
377   void GetEpisodesByFile(const CStdString& strFilenameAndPath, std::vector<CVideoInfoTag>& episodes);
378
379   int SetDetailsForMovie(const CStdString& strFilenameAndPath, const CVideoInfoTag& details);
380   int SetDetailsForTvShow(const CStdString& strPath, const CVideoInfoTag& details);
381   int SetDetailsForEpisode(const CStdString& strFilenameAndPath, const CVideoInfoTag& details, int idShow, int idEpisode=-1);
382   int SetDetailsForMusicVideo(const CStdString& strFilenameAndPath, const CVideoInfoTag& details);
383   void SetStreamDetailsForFile(const CStreamDetails& details, const CStdString &strFileNameAndPath);
384   void SetStreamDetailsForFileId(const CStreamDetails& details, int idFile);
385   void SetDetail(const CStdString& strDetail, int id, int field, VIDEODB_CONTENT_TYPE type);
386
387   void DeleteMovie(const CStdString& strFilenameAndPath, bool bKeepId = false, bool bKeepThumb = false);
388   void DeleteTvShow(const CStdString& strPath, bool bKeepId = false, bool bKeepThumb = false);
389   void DeleteEpisode(const CStdString& strFilenameAndPath, int idEpisode = -1, bool bKeepId = false, bool bKeepThumb = false);
390   void DeleteMusicVideo(const CStdString& strFilenameAndPath, bool bKeepId = false, bool bKeepThumb = false);
391   void DeleteDetailsForTvShow(const CStdString& strPath);
392   void RemoveContentForPath(const CStdString& strPath,CGUIDialogProgress *progress = NULL);
393   void UpdateFanart(const CFileItem &item, VIDEODB_CONTENT_TYPE type);
394   void DeleteSet(int idSet);
395
396   // per-file video settings
397   bool GetVideoSettings(const CStdString &strFilenameAndPath, CVideoSettings &settings);
398   void SetVideoSettings(const CStdString &strFilenameAndPath, const CVideoSettings &settings);
399   void EraseVideoSettings();
400
401   bool GetStackTimes(const CStdString &filePath, std::vector<int> &times);
402   void SetStackTimes(const CStdString &filePath, std::vector<int> &times);
403
404   void GetBookMarksForFile(const CStdString& strFilenameAndPath, VECBOOKMARKS& bookmarks, CBookmark::EType type = CBookmark::STANDARD, bool bAppend=false);
405   void AddBookMarkToFile(const CStdString& strFilenameAndPath, const CBookmark &bookmark, CBookmark::EType type = CBookmark::STANDARD);
406   bool GetResumeBookMark(const CStdString& strFilenameAndPath, CBookmark &bookmark);
407   void DeleteResumeBookMark(const CStdString &strFilenameAndPath);
408   void ClearBookMarkOfFile(const CStdString& strFilenameAndPath, CBookmark& bookmark, CBookmark::EType type = CBookmark::STANDARD);
409   void ClearBookMarksOfFile(const CStdString& strFilenameAndPath, CBookmark::EType type = CBookmark::STANDARD);
410   bool GetBookMarkForEpisode(const CVideoInfoTag& tag, CBookmark& bookmark);
411   void AddBookMarkForEpisode(const CVideoInfoTag& tag, const CBookmark& bookmark);
412   void DeleteBookMarkForEpisode(const CVideoInfoTag& tag);
413
414   // scraper settings
415   void SetScraperForPath(const CStdString& filePath, const ADDON::ScraperPtr& info, const VIDEO::SScanSettings& settings);
416   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath);
417   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath, VIDEO::SScanSettings& settings);
418
419   /*! \brief Retrieve the scraper and settings we should use for the specified path
420    If the scraper is not set on this particular path, we'll recursively check parent folders.
421    \param strPath path to start searching in.
422    \param settings [out] scan settings for this folder.
423    \param foundDirectly [out] true if a scraper was found directly for strPath, false if it was in a parent path.
424    \return A ScraperPtr containing the scraper information. Returns NULL if a trivial (Content == CONTENT_NONE)
425            scraper or no scraper is found.
426    */
427   ADDON::ScraperPtr GetScraperForPath(const CStdString& strPath, VIDEO::SScanSettings& settings, bool& foundDirectly);
428
429   /*! \brief Retrieve the content type of videos in the given path
430    If content is set on the folder, we return the given content type, except in the case of tvshows,
431    where we first check for whether we have episodes directly in the path (thus return episodes) or whether
432    we've found a scraper directly (shows).  Any folders inbetween are treated as seasons (regardless of whether
433    they actually are seasons). Note that any subfolders in movies will be treated as movies.
434    \param strPath path to start searching in.
435    \return A content type string for the current path.
436    */
437   CStdString GetContentForPath(const CStdString& strPath);
438
439   /*! \brief Get a video of the given content type from the given path, if it exists
440    \param content the content type to fetch.
441    \param path the path to fetch a video from.
442    \param item the returned item.
443    \return true if an item is found, false otherwise.
444    */
445   bool GetItemForPath(const CStdString &content, const CStdString &path, CFileItem &item);
446
447   /*! \brief Check whether a given scraper is in use.
448    \param scraperID the scraper to check for.
449    \return true if the scraper is in use, false otherwise.
450    */
451   bool ScraperInUse(const CStdString &scraperID) const;
452   
453   // scanning hashes and paths scanned
454   bool SetPathHash(const CStdString &path, const CStdString &hash);
455   bool GetPathHash(const CStdString &path, CStdString &hash);
456   bool GetPaths(std::set<CStdString> &paths);
457   bool GetPathsForTvShow(int idShow, std::vector<int>& paths);
458
459   /*! \brief retrieve subpaths of a given path.  Assumes a heirarchical folder structure
460    \param basepath the root path to retrieve subpaths for
461    \param subpaths the returned subpaths
462    \return true if we successfully retrieve subpaths (may be zero), false on error
463    */
464   bool GetSubPaths(const CStdString& basepath, std::vector<int>& subpaths);
465
466   // for music + musicvideo linkups - if no album and title given it will return the artist id, else the id of the matching video
467   int GetMatchingMusicVideo(const CStdString& strArtist, const CStdString& strAlbum = "", const CStdString& strTitle = "");
468
469   // searching functions
470   void GetMoviesByActor(const CStdString& strActor, CFileItemList& items);
471   void GetTvShowsByActor(const CStdString& strActor, CFileItemList& items);
472   void GetEpisodesByActor(const CStdString& strActor, CFileItemList& items);
473
474   void GetMusicVideosByArtist(const CStdString& strArtist, CFileItemList& items);
475   void GetMusicVideosByAlbum(const CStdString& strAlbum, CFileItemList& items);
476
477   void GetMovieGenresByName(const CStdString& strSearch, CFileItemList& items);
478   void GetTvShowGenresByName(const CStdString& strSearch, CFileItemList& items);
479   void GetMusicVideoGenresByName(const CStdString& strSearch, CFileItemList& items);
480
481   void GetMovieCountriesByName(const CStdString& strSearch, CFileItemList& items);
482
483   void GetMusicVideoAlbumsByName(const CStdString& strSearch, CFileItemList& items);
484
485   void GetMovieActorsByName(const CStdString& strSearch, CFileItemList& items);
486   void GetTvShowsActorsByName(const CStdString& strSearch, CFileItemList& items);
487   void GetMusicVideoArtistsByName(const CStdString& strSearch, CFileItemList& items);
488
489   void GetMovieDirectorsByName(const CStdString& strSearch, CFileItemList& items);
490   void GetTvShowsDirectorsByName(const CStdString& strSearch, CFileItemList& items);
491   void GetMusicVideoDirectorsByName(const CStdString& strSearch, CFileItemList& items);
492
493   void GetMoviesByName(const CStdString& strSearch, CFileItemList& items);
494   void GetTvShowsByName(const CStdString& strSearch, CFileItemList& items);
495   void GetEpisodesByName(const CStdString& strSearch, CFileItemList& items);
496   void GetMusicVideosByName(const CStdString& strSearch, CFileItemList& items);
497
498   void GetEpisodesByPlot(const CStdString& strSearch, CFileItemList& items);
499   void GetMoviesByPlot(const CStdString& strSearch, CFileItemList& items);
500
501   bool LinkMovieToTvshow(int idMovie, int idShow, bool bRemove);
502   bool IsLinkedToTvshow(int idMovie);
503   bool GetLinksToTvShow(int idMovie, std::vector<int>& ids);
504
505   bool GetArbitraryQuery(const CStdString& strQuery, const CStdString& strOpenRecordSet, const CStdString& strCloseRecordSet,
506                          const CStdString& strOpenRecord, const CStdString& strCloseRecord, const CStdString& strOpenField, const CStdString& strCloseField, CStdString& strResult);
507   bool ArbitraryExec(const CStdString& strExec);
508
509   // general browsing
510   bool GetGenresNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
511   bool GetCountriesNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
512   bool GetStudiosNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
513   bool GetYearsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
514   bool GetActorsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
515   bool GetDirectorsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
516   bool GetWritersNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
517   bool GetSetsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1, const CStdString &where = "");
518   bool GetMusicVideoAlbumsNav(const CStdString& strBaseDir, CFileItemList& items, int idArtist);
519
520   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);
521   bool GetTvShowsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idStudio=-1);
522   bool GetSeasonsNav(const CStdString& strBaseDir, CFileItemList& items, int idActor=-1, int idDirector=-1, int idGenre=-1, int idYear=-1, int idShow=-1);
523   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);
524   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);
525   
526   bool GetRecentlyAddedMoviesNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit=0);
527   bool GetRecentlyAddedEpisodesNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit=0);
528   bool GetRecentlyAddedMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items, unsigned int limit=0);
529
530   bool HasContent();
531   bool HasContent(VIDEODB_CONTENT_TYPE type);
532   bool HasSets() const;
533
534   void CleanDatabase(VIDEO::IVideoInfoScannerObserver* pObserver=NULL, const std::vector<int>* paths=NULL);
535
536   /*! \brief Add a file to the database, if necessary
537    If the file is already in the database, we simply return it's id.
538    \param url - full path of the file to add.
539    \return id of the file, -1 if it could not be added.
540    */
541   int AddFile(const CStdString& url);
542
543   /*! \brief Add a file to the database, if necessary
544    Works for both videodb:// items and normal fileitems
545    \param item CFileItem to add.
546    \return id of the file, -1 if it could not be added.
547    */
548   int AddFile(const CFileItem& item);
549
550   void ExportToXML(const CStdString &path, bool singleFiles = false, bool images=false, bool actorThumbs=false, bool overwrite=false);
551   bool ExportSkipEntry(const CStdString &nfoFile);
552   void ExportActorThumbs(const CStdString &path, const CVideoInfoTag& tag, bool singleFiles, bool overwrite=false);
553   void ImportFromXML(const CStdString &path);
554   void DumpToDummyFiles(const CStdString &path);
555   CStdString GetCachedThumb(const CFileItem& item) const;
556
557   // smart playlists and main retrieval work in these functions
558   bool GetMoviesByWhere(const CStdString& strBaseDir, const CStdString &where, const CStdString &order, CFileItemList& items, bool fetchSets = false);
559   bool GetTvShowsByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items);
560   bool GetEpisodesByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items, bool appendFullShowPath = true);
561   bool GetMusicVideosByWhere(const CStdString &baseDir, const CStdString &whereClause, CFileItemList& items, bool checkLocks = true);
562
563   // partymode
564   int GetMusicVideoCount(const CStdString& strWhere);
565   unsigned int GetMusicVideoIDs(const CStdString& strWhere, std::vector<std::pair<int,int> > &songIDs);
566   bool GetRandomMusicVideo(CFileItem* item, int& idSong, const CStdString& strWhere);
567
568   static void VideoContentTypeToString(VIDEODB_CONTENT_TYPE type, CStdString& out)
569   {
570     switch (type)
571     {
572     case VIDEODB_CONTENT_MOVIES:
573       out = "movie";
574       break;
575     case VIDEODB_CONTENT_TVSHOWS:
576       out = "tvshow";
577       break;
578     case VIDEODB_CONTENT_EPISODES:
579       out = "episode";
580       break;
581     case VIDEODB_CONTENT_MUSICVIDEOS:
582       out = "musicvideo";
583       break;
584     default:
585       break;
586     }
587   }
588
589 protected:
590   int GetMovieId(const CStdString& strFilenameAndPath);
591   int GetMusicVideoId(const CStdString& strFilenameAndPath);
592
593   /*! \brief Get the id of this fileitem
594    Works for both videodb:// items and normal fileitems
595    \param item CFileItem to grab the fileid of
596    \return id of the file, -1 if it is not in the db.
597    */
598   int GetFileId(const CFileItem &item);
599
600   /*! \brief Get the id of a file from path
601    \param url full path to the file
602    \return id of the file, -1 if it is not in the db.
603    */
604   int GetFileId(const CStdString& url);
605
606   int AddPath(const CStdString& strPath);
607   int AddToTable(const CStdString& table, const CStdString& firstField, const CStdString& secondField, const CStdString& value);
608   int AddGenre(const CStdString& strGenre1);
609   int AddActor(const CStdString& strActor, const CStdString& strThumb);
610   int AddCountry(const CStdString& strCountry);
611   int AddSet(const CStdString& strSet);
612   int AddStudio(const CStdString& strStudio1);
613
614   int AddTvShow(const CStdString& strPath);
615   int AddMusicVideo(const CStdString& strFilenameAndPath);
616
617   // link functions - these two do all the work
618   void AddLinkToActor(const char *table, int actorID, const char *secondField, int secondID, const CStdString &role, int order);
619   void AddToLinkTable(const char *table, const char *firstField, int firstID, const char *secondField, int secondID);
620
621   void AddSetToMovie(int idMovie, int idSet);
622
623   void AddActorToMovie(int idMovie, int idActor, const CStdString& strRole, int order);
624   void AddActorToTvShow(int idTvShow, int idActor, const CStdString& strRole, int order);
625   void AddActorToEpisode(int idEpisode, int idActor, const CStdString& strRole, int order);
626   void AddArtistToMusicVideo(int lMVideo, int idArtist);
627
628   void AddDirectorToMovie(int idMovie, int idDirector);
629   void AddDirectorToTvShow(int idTvShow, int idDirector);
630   void AddDirectorToEpisode(int idEpisode, int idDirector);
631   void AddDirectorToMusicVideo(int lMVideo, int idDirector);
632   void AddWriterToEpisode(int idEpisode, int idWriter);
633   void AddWriterToMovie(int idMovie, int idWriter);
634
635   void AddGenreToMovie(int idMovie, int idGenre);
636   void AddGenreToTvShow(int idTvShow, int idGenre);
637   void AddGenreToMusicVideo(int idMVideo, int idGenre);
638
639   void AddStudioToMovie(int idMovie, int idStudio);
640   void AddStudioToTvShow(int idTvShow, int idStudio);
641   void AddStudioToMusicVideo(int idMVideo, int idStudio);
642
643   void AddCountryToMovie(int idMovie, int idCountry);
644
645   void AddGenreAndDirectorsAndStudios(const CVideoInfoTag& details, std::vector<int>& vecDirectors, std::vector<int>& vecGenres, std::vector<int>& vecStudios);
646
647   void DeleteStreamDetails(int idFile);
648   CVideoInfoTag GetDetailsByTypeAndId(VIDEODB_CONTENT_TYPE type, int id);
649   CVideoInfoTag GetDetailsForMovie(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
650   CVideoInfoTag GetDetailsForTvShow(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
651   CVideoInfoTag GetDetailsForEpisode(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
652   CVideoInfoTag GetDetailsForMusicVideo(std::auto_ptr<dbiplus::Dataset> &pDS);
653   void GetCommonDetails(std::auto_ptr<dbiplus::Dataset> &pDS, CVideoInfoTag &details);
654   bool GetPeopleNav(const CStdString& strBaseDir, CFileItemList& items, const CStdString& type, int idContent=-1);
655   bool GetNavCommon(const CStdString& strBaseDir, CFileItemList& items, const CStdString& type, int idContent=-1);
656
657   void GetDetailsFromDB(std::auto_ptr<dbiplus::Dataset> &pDS, int min, int max, const SDbTableOffsets *offsets, CVideoInfoTag &details, int idxOffset = 2);
658   CStdString GetValueString(const CVideoInfoTag &details, int min, int max, const SDbTableOffsets *offsets) const;
659   bool GetStreamDetails(CVideoInfoTag& tag) const;
660
661 private:
662   virtual bool CreateTables();
663   virtual bool UpdateOldVersion(int version);
664
665   /*! \brief (Re)Create the generic database views for movies, tvshows,
666      episodes and music videos
667    */
668   void CreateViews();
669
670   /*! \brief Run a query on the main dataset and return the number of rows
671    If no rows are found we close the dataset and return 0.
672    \param sql the sql query to run
673    \return the number of rows, -1 for an error.
674    */
675   int RunQuery(const CStdString &sql);
676
677   /*! \brief Update routine for base path of videos
678    Only required for videodb version < 44
679    \param table the table to update
680    \param id the primary id in the given table
681    \param column the basepath column to update
682    \param shows whether we're fetching shows (defaults to false)
683    */
684   void UpdateBasePath(const char *table, const char *id, int column, bool shows = false);
685
686   virtual int GetMinVersion() const { return 51; };
687   virtual int GetExportVersion() const { return 1; };
688   const char *GetBaseDBName() const { return "MyVideos"; };
689
690   void ConstructPath(CStdString& strDest, const CStdString& strPath, const CStdString& strFileName);
691   void SplitPath(const CStdString& strFileNameAndPath, CStdString& strPath, CStdString& strFileName);
692   void InvalidatePathHash(const CStdString& strPath);
693   void DeleteThumbForItem(const CStdString& strPath, bool bFolder, int idEpisode = -1);
694
695   bool GetStackedTvShowList(int idShow, CStdString& strIn);
696   void Stack(CFileItemList& items, VIDEODB_CONTENT_TYPE type, bool maintainSortOrder = false);
697
698   /*! \brief Get a safe filename from a given string
699    \param dir directory to use for the file
700    \param name movie, show name, or actor to get a safe filename for
701    \return safe filename based on this title
702    */
703   CStdString GetSafeFile(const CStdString &dir, const CStdString &name) const;
704
705   void AnnounceRemove(std::string content, int id);
706   void AnnounceUpdate(std::string content, int id);
707 };