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