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