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