use separate database files per version for sqlite connections, allowing better ...
[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   CONTENT_TYPE GetContentForPath(const CStdString& strPath);
416   
417   /*! \brief Check whether a given scraper is in use.
418    \param scraperID the scraper to check for.
419    \return true if the scraper is in use, false otherwise.
420    */
421   bool ScraperInUse(const CStdString &scraperID) const;
422   
423   // scanning hashes and paths scanned
424   bool SetPathHash(const CStdString &path, const CStdString &hash);
425   bool GetPathHash(const CStdString &path, CStdString &hash);
426   bool GetPaths(std::set<CStdString> &paths);
427   bool GetPathsForTvShow(int idShow, std::vector<int>& paths);
428
429   /*! \brief retrieve subpaths of a given path.  Assumes a heirarchical folder structure
430    \param basepath the root path to retrieve subpaths for
431    \param subpaths the returned subpaths
432    \return true if we successfully retrieve subpaths (may be zero), false on error
433    */
434   bool GetSubPaths(const CStdString& basepath, std::vector<int>& subpaths);
435
436   // for music + musicvideo linkups - if no album and title given it will return the artist id, else the id of the matching video
437   int GetMatchingMusicVideo(const CStdString& strArtist, const CStdString& strAlbum = "", const CStdString& strTitle = "");
438
439   // searching functions
440   void GetMoviesByActor(const CStdString& strActor, CFileItemList& items);
441   void GetTvShowsByActor(const CStdString& strActor, CFileItemList& items);
442   void GetEpisodesByActor(const CStdString& strActor, CFileItemList& items);
443
444   void GetMusicVideosByArtist(const CStdString& strArtist, CFileItemList& items);
445   void GetMusicVideosByAlbum(const CStdString& strAlbum, CFileItemList& items);
446
447   void GetMovieGenresByName(const CStdString& strSearch, CFileItemList& items);
448   void GetTvShowGenresByName(const CStdString& strSearch, CFileItemList& items);
449   void GetMusicVideoGenresByName(const CStdString& strSearch, CFileItemList& items);
450
451   void GetMovieCountriesByName(const CStdString& strSearch, CFileItemList& items);
452
453   void GetMusicVideoAlbumsByName(const CStdString& strSearch, CFileItemList& items);
454
455   void GetMovieActorsByName(const CStdString& strSearch, CFileItemList& items);
456   void GetTvShowsActorsByName(const CStdString& strSearch, CFileItemList& items);
457   void GetMusicVideoArtistsByName(const CStdString& strSearch, CFileItemList& items);
458
459   void GetMovieDirectorsByName(const CStdString& strSearch, CFileItemList& items);
460   void GetTvShowsDirectorsByName(const CStdString& strSearch, CFileItemList& items);
461   void GetMusicVideoDirectorsByName(const CStdString& strSearch, CFileItemList& items);
462
463   void GetMoviesByName(const CStdString& strSearch, CFileItemList& items);
464   void GetTvShowsByName(const CStdString& strSearch, CFileItemList& items);
465   void GetEpisodesByName(const CStdString& strSearch, CFileItemList& items);
466   void GetMusicVideosByName(const CStdString& strSearch, CFileItemList& items);
467
468   void GetEpisodesByPlot(const CStdString& strSearch, CFileItemList& items);
469   void GetMoviesByPlot(const CStdString& strSearch, CFileItemList& items);
470
471   bool LinkMovieToTvshow(int idMovie, int idShow, bool bRemove);
472   bool IsLinkedToTvshow(int idMovie);
473   bool GetLinksToTvShow(int idMovie, std::vector<int>& ids);
474
475   bool GetArbitraryQuery(const CStdString& strQuery, const CStdString& strOpenRecordSet, const CStdString& strCloseRecordSet,
476                          const CStdString& strOpenRecord, const CStdString& strCloseRecord, const CStdString& strOpenField, const CStdString& strCloseField, CStdString& strResult);
477   bool ArbitraryExec(const CStdString& strExec);
478
479   // general browsing
480   bool GetGenresNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
481   bool GetCountriesNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
482   bool GetStudiosNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
483   bool GetYearsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
484   bool GetActorsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
485   bool GetDirectorsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
486   bool GetWritersNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1);
487   bool GetSetsNav(const CStdString& strBaseDir, CFileItemList& items, int idContent=-1, const CStdString &where = "");
488   bool GetMusicVideoAlbumsNav(const CStdString& strBaseDir, CFileItemList& items, int idArtist);
489
490   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);
491   bool GetTvShowsNav(const CStdString& strBaseDir, CFileItemList& items, int idGenre=-1, int idYear=-1, int idActor=-1, int idDirector=-1, int idStudio=-1);
492   bool GetSeasonsNav(const CStdString& strBaseDir, CFileItemList& items, int idActor=-1, int idDirector=-1, int idGenre=-1, int idYear=-1, int idShow=-1);
493   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);
494   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);
495
496   bool GetRecentlyAddedMoviesNav(const CStdString& strBaseDir, CFileItemList& items);
497   bool GetRecentlyAddedEpisodesNav(const CStdString& strBaseDir, CFileItemList& items);
498   bool GetRecentlyAddedMusicVideosNav(const CStdString& strBaseDir, CFileItemList& items);
499
500   bool HasContent();
501   bool HasContent(VIDEODB_CONTENT_TYPE type);
502   bool HasSets() const;
503
504   void CleanDatabase(VIDEO::IVideoInfoScannerObserver* pObserver=NULL, const std::vector<int>* paths=NULL);
505
506   /*! \brief Add a file to the database, if necessary
507    If the file is already in the database, we simply return it's id.
508    \param url - full path of the file to add.
509    \return id of the file, -1 if it could not be added.
510    */
511   int AddFile(const CStdString& url);
512
513   /*! \brief Add a file to the database, if necessary
514    Works for both videodb:// items and normal fileitems
515    \param item CFileItem to add.
516    \return id of the file, -1 if it could not be added.
517    */
518   int AddFile(const CFileItem& item);
519
520   void ExportToXML(const CStdString &path, bool singleFiles = false, bool images=false, bool actorThumbs=false, bool overwrite=false);
521   bool ExportSkipEntry(const CStdString &nfoFile);
522   void ExportActorThumbs(const CStdString &path, const CVideoInfoTag& tag, bool singleFiles, bool overwrite=false);
523   void ImportFromXML(const CStdString &path);
524   void DumpToDummyFiles(const CStdString &path);
525   CStdString GetCachedThumb(const CFileItem& item) const;
526
527   // smart playlists and main retrieval work in these functions
528   bool GetMoviesByWhere(const CStdString& strBaseDir, const CStdString &where, const CStdString &order, CFileItemList& items, bool fetchSets = false);
529   bool GetTvShowsByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items);
530   bool GetEpisodesByWhere(const CStdString& strBaseDir, const CStdString &where, CFileItemList& items, bool appendFullShowPath = true);
531   bool GetMusicVideosByWhere(const CStdString &baseDir, const CStdString &whereClause, CFileItemList& items, bool checkLocks = true);
532
533   // partymode
534   int GetMusicVideoCount(const CStdString& strWhere);
535   unsigned int GetMusicVideoIDs(const CStdString& strWhere, std::vector<std::pair<int,int> > &songIDs);
536   bool GetRandomMusicVideo(CFileItem* item, int& idSong, const CStdString& strWhere);
537
538   static void VideoContentTypeToString(VIDEODB_CONTENT_TYPE type, CStdString& out)
539   {
540     switch (type)
541     {
542     case VIDEODB_CONTENT_MOVIES:
543       out = "movie";
544       break;
545     case VIDEODB_CONTENT_TVSHOWS:
546       out = "tvshow";
547       break;
548     case VIDEODB_CONTENT_EPISODES:
549       out = "episode";
550       break;
551     case VIDEODB_CONTENT_MUSICVIDEOS:
552       out = "musicvideo";
553       break;
554     default:
555       break;
556     }
557   }
558
559 protected:
560   int GetMovieId(const CStdString& strFilenameAndPath);
561   int GetMusicVideoId(const CStdString& strFilenameAndPath);
562
563   /*! \brief Get the id of this fileitem
564    Works for both videodb:// items and normal fileitems
565    \param item CFileItem to grab the fileid of
566    \return id of the file, -1 if it is not in the db.
567    */
568   int GetFileId(const CFileItem &item);
569
570   /*! \brief Get the id of a file from path
571    \param url full path to the file
572    \return id of the file, -1 if it is not in the db.
573    */
574   int GetFileId(const CStdString& url);
575
576   int AddPath(const CStdString& strPath);
577   int AddToTable(const CStdString& table, const CStdString& firstField, const CStdString& secondField, const CStdString& value);
578   int AddGenre(const CStdString& strGenre1);
579   int AddActor(const CStdString& strActor, const CStdString& strThumb);
580   int AddCountry(const CStdString& strCountry);
581   int AddSet(const CStdString& strSet);
582   int AddStudio(const CStdString& strStudio1);
583
584   int AddTvShow(const CStdString& strPath);
585   int AddMusicVideo(const CStdString& strFilenameAndPath);
586
587   // link functions - these two do all the work
588   void AddLinkToActor(const char *table, int actorID, const char *secondField, int secondID, const CStdString &role);
589   void AddToLinkTable(const char *table, const char *firstField, int firstID, const char *secondField, int secondID);
590
591   void AddSetToMovie(int idMovie, int idSet);
592
593   void AddActorToMovie(int idMovie, int idActor, const CStdString& strRole);
594   void AddActorToTvShow(int idTvShow, int idActor, const CStdString& strRole);
595   void AddActorToEpisode(int idEpisode, int idActor, const CStdString& strRole);
596   void AddArtistToMusicVideo(int lMVideo, int idArtist);
597
598   void AddDirectorToMovie(int idMovie, int idDirector);
599   void AddDirectorToTvShow(int idTvShow, int idDirector);
600   void AddDirectorToEpisode(int idEpisode, int idDirector);
601   void AddDirectorToMusicVideo(int lMVideo, int idDirector);
602   void AddWriterToEpisode(int idEpisode, int idWriter);
603   void AddWriterToMovie(int idMovie, int idWriter);
604
605   void AddGenreToMovie(int idMovie, int idGenre);
606   void AddGenreToTvShow(int idTvShow, int idGenre);
607   void AddGenreToMusicVideo(int idMVideo, int idGenre);
608
609   void AddStudioToMovie(int idMovie, int idStudio);
610   void AddStudioToTvShow(int idTvShow, int idStudio);
611   void AddStudioToMusicVideo(int idMVideo, int idStudio);
612
613   void AddCountryToMovie(int idMovie, int idCountry);
614
615   void AddGenreAndDirectorsAndStudios(const CVideoInfoTag& details, std::vector<int>& vecDirectors, std::vector<int>& vecGenres, std::vector<int>& vecStudios);
616
617   void DeleteStreamDetails(int idFile);
618   CVideoInfoTag GetDetailsByTypeAndId(VIDEODB_CONTENT_TYPE type, int id);
619   CVideoInfoTag GetDetailsForMovie(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
620   CVideoInfoTag GetDetailsForTvShow(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
621   CVideoInfoTag GetDetailsForEpisode(std::auto_ptr<dbiplus::Dataset> &pDS, bool needsCast = false);
622   CVideoInfoTag GetDetailsForMusicVideo(std::auto_ptr<dbiplus::Dataset> &pDS);
623   void GetCommonDetails(std::auto_ptr<dbiplus::Dataset> &pDS, CVideoInfoTag &details);
624   bool GetPeopleNav(const CStdString& strBaseDir, CFileItemList& items, const CStdString& type, int idContent=-1);
625   bool GetNavCommon(const CStdString& strBaseDir, CFileItemList& items, const CStdString& type, int idContent=-1);
626
627   void GetDetailsFromDB(std::auto_ptr<dbiplus::Dataset> &pDS, int min, int max, const SDbTableOffsets *offsets, CVideoInfoTag &details, int idxOffset = 2);
628   CStdString GetValueString(const CVideoInfoTag &details, int min, int max, const SDbTableOffsets *offsets) const;
629
630 private:
631   virtual bool CreateTables();
632   virtual bool UpdateOldVersion(int version);
633
634   /*! \brief Run a query on the main dataset and return the number of rows
635    If no rows are found we close the dataset and return 0.
636    \param sql the sql query to run
637    \return the number of rows, -1 for an error.
638    */
639   int RunQuery(const CStdString &sql);
640
641   virtual int GetMinVersion() const { return 44; };
642   const char *GetBaseDBName() const { return "MyVideos"; };
643
644   void ConstructPath(CStdString& strDest, const CStdString& strPath, const CStdString& strFileName);
645   void SplitPath(const CStdString& strFileNameAndPath, CStdString& strPath, CStdString& strFileName);
646   void InvalidatePathHash(const CStdString& strPath);
647   void DeleteThumbForItem(const CStdString& strPath, bool bFolder, int idEpisode = -1);
648
649   bool GetStackedTvShowList(int idShow, CStdString& strIn);
650   void Stack(CFileItemList& items, VIDEODB_CONTENT_TYPE type, bool maintainSortOrder = false);
651
652   /*! \brief Get a safe filename from a given string
653    \param dir directory to use for the file
654    \param name movie, show name, or actor to get a safe filename for
655    \return safe filename based on this title
656    */
657   CStdString GetSafeFile(const CStdString &dir, const CStdString &name) const;
658
659   void AnnounceRemove(std::string content, int id);
660   void AnnounceUpdate(std::string content, int id);
661 };