[XBOX] Merged: Linuxport revisions
[xbmc:xbmc-antiquated.git] / xbmc / MusicDatabase.h
1 /*
2  *      Copyright (C) 2005-2008 Team XBMC
3  *      http://www.xbmc.org
4  *
5  *  This Program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This Program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with XBMC; see the file COPYING.  If not, write to
17  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  http://www.gnu.org/copyleft/gpl.html
19  *
20  */
21 /*!
22  \file MusicDatabase.h
23 \brief
24 */
25 #pragma once
26 #include "Database.h"
27 #include "Album.h"
28 #include "StringUtils.h"
29
30 struct SScraperInfo;
31
32 class CArtist;
33 class CFileItem;
34
35 #include <set>
36
37 // return codes of Cleaning up the Database
38 // numbers are strings from strings.xml
39 #define ERROR_OK     317
40 #define ERROR_CANCEL    0
41 #define ERROR_DATABASE    315
42 #define ERROR_REORG_SONGS   319
43 #define ERROR_REORG_ARTIST   321
44 #define ERROR_REORG_GENRE   323
45 #define ERROR_REORG_PATH   325
46 #define ERROR_REORG_ALBUM   327
47 #define ERROR_WRITING_CHANGES  329
48 #define ERROR_COMPRESSING   332
49
50 #define NUM_SONGS_BEFORE_COMMIT 500
51
52 /*!
53  \ingroup music
54  \brief A set of CStdString objects, used for CMusicDatabase
55  \sa ISETPATHES, CMusicDatabase
56  */
57 typedef std::set<CStdString> SETPATHES;
58
59 /*!
60  \ingroup music
61  \brief The SETPATHES iterator
62  \sa SETPATHES, CMusicDatabase
63  */
64 typedef std::set<CStdString>::iterator ISETPATHES;
65
66 /*!
67  \ingroup music
68  \brief A vector of longs for iDs, used for CMusicDatabase's multiple artist/genre capability
69  */
70 typedef std::vector<long> VECLONGS;
71
72 class CGUIDialogProgress;
73 class CFileItemList;
74
75 /*!
76  \ingroup music
77  \brief Class to store and read tag information
78
79  CMusicDatabase can be used to read and store
80  tag information for faster access. It is based on
81  sqlite (http://www.sqlite.org).
82
83  Here is the database layout:
84   \image html musicdatabase.png
85
86  \sa CAlbum, CSong, VECSONGS, CMapSong, VECARTISTS, VECALBUMS, VECGENRES
87  */
88 class CMusicDatabase : public CDatabase
89 {
90   class CArtistCache
91   {
92   public:
93     long idArtist;
94     CStdString strArtist;
95   };
96
97   class CPathCache
98   {
99   public:
100     long idPath;
101     CStdString strPath;
102   };
103
104   class CGenreCache
105   {
106   public:
107     long idGenre;
108     CStdString strGenre;
109   };
110
111   class CAlbumCache : public CAlbum
112   {
113   public:
114     long idAlbum;
115     long idArtist;
116   };
117
118 public:
119   CMusicDatabase(void);
120   virtual ~CMusicDatabase(void);
121
122   virtual bool CommitTransaction();
123   void EmptyCache();
124   void Clean();
125   int  Cleanup(CGUIDialogProgress *pDlgProgress);
126   void DeleteAlbumInfo();
127   bool LookupCDDBInfo(bool bRequery=false);
128   void DeleteCDDBInfo();
129   void AddSong(const CSong& song, bool bCheck = true);
130   long SetAlbumInfo(long idAlbum, const CAlbum& album, const VECSONGS& songs, bool bTransaction=true);
131   bool DeleteAlbumInfo(long idArtist);
132   long SetArtistInfo(long idArtist, const CArtist& artist);
133   bool DeleteArtistInfo(long idArtist);
134   bool GetAlbumInfo(long idAlbum, CAlbum &info, VECSONGS* songs);
135   bool HasAlbumInfo(long idAlbum);
136   bool GetArtistInfo(long idArtist, CArtist &info, bool needAll=true);
137   bool GetSongByFileName(const CStdString& strFileName, CSong& song);
138   long GetAlbumIdByPath(const CStdString& path);
139   bool GetSongById(long idSong, CSong& song);
140 #ifdef HAS_NEW_KARAOKE
141   bool GetSongByKaraokeNumber( long number, CSong& song );
142   bool SetKaraokeSongDelay( long idSong, int delay );
143 #endif
144   bool GetSongsByPath(const CStdString& strPath, CSongMap& songs, bool bAppendToMap = false);
145   bool Search(const CStdString& search, CFileItemList &items);
146
147   bool GetAlbumFromSong(long idSong, CAlbum &album);
148   bool GetAlbumFromSong(const CSong &song, CAlbum &album);
149
150   bool GetArbitraryQuery(const CStdString& strQuery, const CStdString& strOpenRecordSet, const CStdString& strCloseRecordSet,
151                          const CStdString& strOpenRecord, const CStdString& strCloseRecord, const CStdString& strOpenField, const CStdString& strCloseField, CStdString& strResult);
152   bool ArbitraryExec(const CStdString& strExec);
153
154   bool GetTop100(const CStdString& strBaseDir, CFileItemList& items);
155   bool GetTop100Albums(VECALBUMS& albums);
156   bool GetTop100AlbumSongs(const CStdString& strBaseDir, CFileItemList& item);
157   bool GetRecentlyAddedAlbums(VECALBUMS& albums);
158   bool GetRecentlyAddedAlbumSongs(const CStdString& strBaseDir, CFileItemList& item);
159   bool GetRecentlyPlayedAlbums(VECALBUMS& albums);
160   bool GetRecentlyPlayedAlbumSongs(const CStdString& strBaseDir, CFileItemList& item);
161   bool IncrTop100CounterByFileName(const CStdString& strFileName1);
162   bool RemoveSongsFromPath(const CStdString &path, CSongMap &songs);
163   bool CleanupOrphanedItems();
164   bool GetPaths(std::set<CStdString> &paths);
165   bool SetPathHash(const CStdString &path, const CStdString &hash);
166   bool GetPathHash(const CStdString &path, CStdString &hash);
167   bool GetGenresNav(const CStdString& strBaseDir, CFileItemList& items);
168   bool GetYearsNav(const CStdString& strBaseDir, CFileItemList& items);
169   bool GetArtistsNav(const CStdString& strBaseDir, CFileItemList& items, long idGenre, bool albumArtistsOnly);
170   bool GetAlbumsNav(const CStdString& strBaseDir, CFileItemList& items, long idGenre, long idArtist);
171   bool GetAlbumsByYear(const CStdString &strBaseDir, CFileItemList& items, long year);
172   bool GetSongsNav(const CStdString& strBaseDir, CFileItemList& items, long idGenre, long idArtist,long idAlbum);
173   bool GetSongsByYear(const CStdString& baseDir, CFileItemList& items, long year);
174   bool GetSongsByWhere(const CStdString &baseDir, const CStdString &whereClause, CFileItemList& items);
175   bool GetAlbumsByWhere(const CStdString &baseDir, const CStdString &where, const CStdString &order, CFileItemList &items);
176   bool GetRandomSong(CFileItem* item, long& lSongId, const CStdString& strWhere);
177   int GetKaraokeSongsCount();
178   int GetSongsCount(const CStdString& strWhere = "");
179   unsigned int GetSongIDs(const CStdString& strWhere, std::vector<std::pair<int,long> > &songIDs);
180
181   bool GetAlbumPath(long idAlbum, CStdString &path);
182   bool SaveAlbumThumb(long idAlbum, const CStdString &thumb);
183   bool GetAlbumThumb(long idAlbum, CStdString &thumb);
184   bool GetArtistPath(long idArtist, CStdString &path);
185
186   bool GetGenreById(long idGenre, CStdString& strGenre);
187   bool GetArtistById(long idArtist, CStdString& strArtist);
188   bool GetAlbumById(long idAlbum, CStdString& strAlbum);
189
190   long GetArtistByName(const CStdString& strArtist);
191   long GetAlbumByName(const CStdString& strAlbum, const CStdString& strArtist="");
192   long GetGenreByName(const CStdString& strGenre);
193   long GetSongByArtistAndAlbumAndTitle(const CStdString& strArtist, const CStdString& strAlbum, const CStdString& strTitle);
194
195   bool GetVariousArtistsAlbums(const CStdString& strBaseDir, CFileItemList& items);
196   bool GetVariousArtistsAlbumsSongs(const CStdString& strBaseDir, CFileItemList& items);
197
198   bool SetSongRating(const CStdString &filePath, char rating);
199   bool SetScraperForPath(const CStdString& strPath, const SScraperInfo& info);
200   bool GetScraperForPath(const CStdString& strPath, SScraperInfo& info);
201
202   void ExportToXML(const CStdString &xmlFile, bool singleFiles = false, bool images=false, bool overwrite=false);
203   void ImportFromXML(const CStdString &xmlFile);
204 #ifdef HAS_NEW_KARAOKE
205   void ExportKaraokeInfo(const CStdString &outFile, bool asHTML );
206   void ImportKaraokeInfo(const CStdString &inputFile );
207 #endif
208 protected:
209   std::map<CStdString, int /*CArtistCache*/> m_artistCache;
210   std::map<CStdString, int /*CGenreCache*/> m_genreCache;
211   std::map<CStdString, int /*CPathCache*/> m_pathCache;
212   std::map<CStdString, int /*CPathCache*/> m_thumbCache;
213   std::map<CStdString, CAlbumCache> m_albumCache;
214   virtual bool CreateTables();
215   long AddAlbum(const CStdString& strAlbum1, long lArtistId, const CStdString &extraArtists, const CStdString &strArtist1, long idThumb, long idGenre, const CStdString &extraGenres, long year);
216   long AddGenre(const CStdString& strGenre);
217   long AddArtist(const CStdString& strArtist);
218   long AddPath(const CStdString& strPath);
219   long AddThumb(const CStdString& strThumb1);
220   void AddExtraAlbumArtists(const CStdStringArray& vecArtists, long lAlbumId);
221   void AddExtraSongArtists(const CStdStringArray& vecArtists, long lSongId, bool bCheck = true);
222 #ifdef HAS_NEW_KARAOKE
223   void AddKaraokeData(const CSong& song);
224 #endif
225   void AddExtraGenres(const CStdStringArray& vecGenres, long lSongId, long lAlbumId, bool bCheck = true);
226   bool SetAlbumInfoSongs(long idAlbumInfo, const VECSONGS& songs);
227   bool GetAlbumInfoSongs(long idAlbumInfo, VECSONGS& songs);
228 private:
229   void SplitString(const CStdString &multiString, std::vector<CStdString> &vecStrings, CStdString &extraStrings);
230   CSong GetSongFromDataset(bool bWithMusicDbPath=false);
231   CArtist GetArtistFromDataset(dbiplus::Dataset* pDS, bool needThumb=true);
232   CAlbum GetAlbumFromDataset(dbiplus::Dataset* pDS, bool imageURL=false);
233   void GetFileItemFromDataset(CFileItem* item, const CStdString& strMusicDBbasePath);
234   bool CleanupSongs();
235   bool CleanupSongsByIds(const CStdString &strSongIds);
236   bool CleanupPaths();
237   bool CleanupThumbs();
238   bool CleanupAlbums();
239   bool CleanupArtists();
240   bool CleanupGenres();
241   virtual bool UpdateOldVersion(int version);
242   bool SearchArtists(const CStdString& search, CFileItemList &artists);
243   bool SearchAlbums(const CStdString& search, CFileItemList &albums);
244   bool SearchSongs(const CStdString& strSearch, CFileItemList &songs);
245   long GetSongIDFromPath(const CStdString &filePath);
246
247   // Fields should be ordered as they
248   // appear in the songview
249   enum _SongFields
250   {
251     song_idSong=0,
252     song_strExtraArtists,
253     song_strExtraGenres,
254     song_strTitle,
255     song_iTrack,
256     song_iDuration,
257     song_iYear,
258     song_dwFileNameCRC,
259     song_strFileName,
260     song_strMusicBrainzTrackID,
261     song_strMusicBrainzArtistID,
262     song_strMusicBrainzAlbumID,
263     song_strMusicBrainzAlbumArtistID,
264     song_strMusicBrainzTRMID,
265     song_iTimesPlayed,
266     song_iStartOffset,
267     song_iEndOffset,
268     song_lastplayed,
269     song_rating,
270     song_comment,
271     song_idAlbum,
272     song_strAlbum,
273     song_strPath,
274     song_idArtist,
275     song_strArtist,
276     song_idGenre,
277     song_strGenre,
278     song_strThumb,
279     song_iKarNumber,
280     song_iKarDelay,
281     song_strKarEncoding
282   } SongFields;
283
284   // Fields should be ordered as they
285   // appear in the albumview
286   enum _AlbumFields
287   {
288     album_idAlbum=0,
289     album_strAlbum,
290     album_strExtraArtists,
291     album_idArtist,
292     album_strExtraGenres,
293     album_idGenre,
294     album_strArtist,
295     album_strGenre,
296     album_iYear,
297     album_strThumb,
298     album_idAlbumInfo,
299     album_strMoods,
300     album_strStyles,
301     album_strThemes,
302     album_strReview,
303     album_strLabel,
304     album_strType,
305     album_strThumbURL,
306     album_iRating
307   } AlbumFields;
308
309   enum _ArtistFields
310   {
311     artist_idArtist=1, // not a typo - we have the primary key @ 0
312     artist_strBorn,
313     artist_strFormed,
314     artist_strGenres,
315     artist_strMoods,
316     artist_strStyles,
317     artist_strInstruments,
318     artist_strBiography,
319     artist_strDied,
320     artist_strDisbanded,
321     artist_strYearsActive,
322     artist_strImage,
323     artist_strFanart
324   } ArtistFields;
325 };