]> git.sesse.net Git - vlc/blob - modules/media_library/sql_add.c
fix album art caching for files without artist/album tags
[vlc] / modules / media_library / sql_add.c
1 /*****************************************************************************
2  * sql_media_library.c: SQL-based media library
3  *****************************************************************************
4  * Copyright (C) 2008-2010 the VideoLAN Team and AUTHORS
5  * $Id$
6  *
7  * Authors: Antoine Lejeune <phytos@videolan.org>
8  *          Jean-Philippe André <jpeg@videolan.org>
9  *          Rémi Duraffort <ivoire@videolan.org>
10  *          Adrien Maglo <magsoft@videolan.org>
11  *          Srikanth Raju <srikiraju at gmail dot com>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26  *****************************************************************************/
27
28 #include "sql_media_library.h"
29
30 /*****************************************************************************
31  * ADD FUNCTIONS
32  *****************************************************************************/
33
34 /**
35  * @brief Add element to ML based on a ml_media_t (media ID ignored)
36  * @param p_ml This media_library_t object
37  * @param p_media media item to add in the DB. The media_id is ignored
38  * @return VLC_SUCCESS or VLC_EGENERIC
39  * @note This function is threadsafe
40  */
41 int AddMedia( media_library_t *p_ml, ml_media_t *p_media )
42 {
43     int i_ret = VLC_SUCCESS;
44     int i_album_artist = 0;
45
46     Begin( p_ml );
47     ml_LockMedia( p_media );
48     assert( p_media->i_id == 0 );
49     /* Add any people */
50     ml_person_t* person = p_media->p_people;
51     while( person )
52     {
53         if( person->i_id <= 0 )
54         {
55             if( person->psz_name )
56             {
57                 person->i_id = ml_GetInt( p_ml, ML_PEOPLE_ID, person->psz_role,
58                                             ML_PEOPLE, person->psz_role,
59                                             person->psz_name );
60                 if( person->i_id <= 0 )
61                 {
62                     /* Create person */
63                     AddPeople( p_ml, person->psz_name, person->psz_role );
64                     person->i_id = ml_GetInt( p_ml, ML_PEOPLE_ID, person->psz_role,
65                                             ML_PEOPLE, person->psz_role,
66                                             person->psz_name );
67                 }
68
69             }
70         }
71         if( strcmp( person->psz_role, ML_PERSON_ALBUM_ARTIST ) == 0 )
72             i_album_artist = person->i_id;
73         person = person->p_next;
74     }
75
76     /* Album id */
77     if( p_media->i_album_id <= 0 )
78     {
79         if( p_media->psz_album )
80         {
81             /* TODO:Solidly incorporate Album artist */
82             int i_album_id = ml_GetAlbumId( p_ml, p_media->psz_album );
83             if( i_album_id <= 0 )
84             {
85                 /* Create album */
86                 i_ret = AddAlbum( p_ml, p_media->psz_album, p_media->psz_cover,
87                                     i_album_artist );
88                 if( i_ret != VLC_SUCCESS )
89                     return i_ret;
90                 i_album_id = ml_GetAlbumId( p_ml, p_media->psz_album );
91                 if( i_album_id <= 0 )
92                     return i_ret;
93             }
94             p_media->i_album_id = i_album_id;
95         }
96     }
97
98
99     if( !p_media->psz_uri || !*p_media->psz_uri )
100     {
101         msg_Dbg( p_ml, "cannot add a media without uri (%s)", __func__ );
102         return VLC_EGENERIC;
103     }
104
105     i_ret = QuerySimple( p_ml,
106             "INSERT INTO media ( uri, title, original_title, genre, type, "
107             "comment, cover, preview, year, track, disc, album_id, vote, score, "
108             "duration, first_played, played_count, last_played, "
109             "skipped_count, last_skipped, import_time, filesize ) "
110             "VALUES ( %Q, %Q, %Q, %Q, '%d',%Q, %Q, %Q, '%d', '%d', '%d', '%d',"
111             "'%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d' )",
112                 p_media->psz_uri,
113                 p_media->psz_title,
114                 p_media->psz_orig_title,
115                 p_media->psz_genre,
116                 (int)p_media->i_type,
117                 p_media->psz_comment,
118                 p_media->psz_cover,
119                 p_media->psz_preview,
120                 (int)p_media->i_year,
121                 (int)p_media->i_track_number,
122                 (int)p_media->i_disc_number,
123                 (int)p_media->i_album_id,
124                 (int)p_media->i_vote,
125                 (int)p_media->i_score,
126                 (int)p_media->i_duration,
127                 (int)p_media->i_first_played,
128                 (int)p_media->i_played_count,
129                 (int)p_media->i_last_played,
130                 (int)p_media->i_skipped_count,
131                 (int)p_media->i_last_skipped,
132                 (int)p_media->i_import_time,
133                 (int)p_media->i_filesize );
134     if( i_ret != VLC_SUCCESS )
135         goto quit_addmedia;
136
137     int id = GetMediaIdOfURI( p_ml, p_media->psz_uri );
138     if( id <= 0 )
139     {
140         i_ret = VLC_EGENERIC;
141         goto quit_addmedia;
142     }
143
144     p_media->i_id = id;
145     person = p_media->p_people;
146     if( !person )
147     {
148         /* If there is no person, set it to "Unknown", ie. people_id=0 */
149         i_ret = QuerySimple( p_ml, "INSERT into media_to_people ( media_id, "
150                                      "people_id ) VALUES ( %d, %d )",
151                                      id, 0 );
152         if( i_ret != VLC_SUCCESS )
153             goto quit_addmedia;
154     } else {
155         while( person )
156         {
157             i_ret = QuerySimple( p_ml, "INSERT into media_to_people ( media_id, "
158                                          "people_id ) VALUES ( %d, %d )",
159                                          id, person->i_id );
160             if( i_ret != VLC_SUCCESS )
161                 goto quit_addmedia;
162             person = person->p_next;
163         }
164     }
165
166     i_ret = QuerySimple( p_ml, "INSERT into extra ( id, extra, language, bitrate, "
167             "samplerate, bpm ) VALUES ( '%d', %Q, %Q, '%d', '%d', '%d' )",
168             id, p_media->psz_extra, p_media->psz_language,
169             p_media->i_bitrate, p_media->i_samplerate, p_media->i_bpm );
170     if( i_ret != VLC_SUCCESS )
171         goto quit_addmedia;
172     i_ret = pool_InsertMedia( p_ml, p_media, true );
173
174 quit_addmedia:
175     if( i_ret == VLC_SUCCESS )
176     {
177         Commit( p_ml );
178     }
179     else
180         Rollback( p_ml );
181     ml_UnlockMedia( p_media );
182     if( i_ret == VLC_SUCCESS )
183         var_SetInteger( p_ml, "media-added", id );
184     return i_ret;
185 }
186
187
188 /**
189  * @brief Add generic album to ML
190  *
191  * @param p_ml this Media Library
192  * @param psz_title album title, cannot be null
193  * @param psz_cover album cover, can be null
194  * @return VLC_SUCCESS or a VLC error code
195  *
196  * This will add a new in the album table, without checking if album is
197  * already present (or another album with same title)
198  */
199 int AddAlbum( media_library_t *p_ml, const char *psz_title,
200         const char *psz_cover, const int i_album_artist )
201 {
202     assert( p_ml );
203
204     if( !psz_title || !*psz_title )
205     {
206         msg_Warn( p_ml, "tried to add an album without title" );
207         return VLC_EGENERIC;
208     }
209     msg_Dbg( p_ml, "New album: '%s'", psz_title );
210
211     int i_ret = QuerySimple( p_ml,
212                         "INSERT INTO album ( title, cover, album_artist_id ) "
213                         "VALUES ( %Q, %Q, '%d' )",
214                         psz_title , psz_cover, i_album_artist );
215
216     return i_ret;
217 }
218
219
220 /**
221  * @brief Add generic people to ML
222  *
223  * @param p_ml this Media Library
224  * @param psz_title name
225  * @param i_role role: 1 for artist, 2 for publisher
226  * @return VLC_SUCCESS or a VLC error code
227  *
228  * This will add a new in the album table, without checking if album is
229  * already present (or another album with same title)
230  */
231 int AddPeople( media_library_t *p_ml, const char *psz_name,
232         const char* psz_role )
233 {
234     assert( p_ml );
235     assert( psz_role && *psz_role );
236
237     if( !psz_name || !*psz_name )
238     {
239         msg_Warn( p_ml, "tried to add an artist without name" );
240         return VLC_EGENERIC;
241     }
242     msg_Dbg( p_ml, "New people: (%s) '%s'", psz_role, psz_name );
243
244     int i_ret = QuerySimple( p_ml,
245                              "INSERT INTO people ( name, role ) "
246                              "VALUES ( %Q, %Q )",
247                              psz_name, psz_role );
248
249     return i_ret;
250 }
251
252 /**
253  * @brief Add element to ML based on an Input Item
254  * @param p_ml This media_library_t object
255  * @param p_input input item to add
256  * @return VLC_SUCCESS or VLC_EGENERIC
257  */
258 int AddInputItem( media_library_t *p_ml, input_item_t *p_input )
259 {
260     assert( p_ml );
261     if( !p_input || !p_input->psz_uri )
262         return VLC_EGENERIC;
263     int i_ret = VLC_SUCCESS;
264
265     vlc_gc_incref( p_input );
266
267     /* Check input item is not already in the ML */
268     i_ret = GetMediaIdOfInputItem( p_ml, p_input );
269     if( i_ret > 0 )
270     {
271         msg_Dbg( p_ml, "Item already in Media Library (id: %d)", i_ret );
272         vlc_gc_decref( p_input );
273         return VLC_SUCCESS;
274     }
275
276     ml_media_t* p_media = media_New( p_ml, 0, ML_MEDIA, false );
277
278     /* Add media to the database */
279     CopyInputItemToMedia( p_media, p_input );
280     i_ret = AddMedia( p_ml, p_media );
281     if( i_ret == VLC_SUCCESS )
282         watch_add_Item( p_ml, p_input, p_media );
283     ml_gc_decref( p_media );
284     vlc_gc_decref( p_input );
285     return i_ret;
286 }
287
288
289 /**
290  * @brief Add element to ML based on a Playlist Item
291  *
292  * @param p_ml the media library object
293  * @param p_playlist_item playlist_item to add
294  * @return VLC_SUCCESS or VLC_EGENERIC
295  */
296 int AddPlaylistItem( media_library_t *p_ml, playlist_item_t *p_playlist_item )
297 {
298     if( !p_playlist_item )
299         return VLC_EGENERIC;
300
301     return AddInputItem( p_ml, p_playlist_item->p_input );
302 }
303