1 #ifndef __lib_components_mediadatabase_h_
2 #define __lib_components_mediadatabase_h_
4 #include <lib/base/message.h>
5 #include <lib/base/stl_types.h>
6 #include <lib/base/thread.h>
7 #include <lib/components/file_monitor.h>
8 #include <lib/components/media_scanner.h>
11 #include <QSqlDatabase>
16 std::string query_string;
26 insert_result(long long id = 0, bool created = true, bool error = false, bool skipped = false) :
27 id(id), created(created), error(error), skipped(skipped)
33 class eMediaDatabaseHandler;
35 class eMediaDatabaseResult : public iObject
37 DECLARE_REF(eMediaDatabaseResult)
41 std::string m_errorDriverText;
42 std::string m_errorDatabaseText;
43 stringMapVector m_data;
46 eMediaDatabaseResult();
47 ~eMediaDatabaseResult();
49 bool error(){ return m_error; };
50 int rowsAffected(){ return m_rowsAffected; };
51 int lastInsertId(){ return m_lastInsertId; };
52 std::string errorDriverText(){ return m_errorDriverText; };
53 std::string errorDatabaseText(){ return m_errorDatabaseText; };
54 stringMapVector data(){ return m_data; };
56 void setError(bool error){ m_error = error; };
57 void setRowsAffected(int rowsAffected){ m_rowsAffected = rowsAffected; };
58 void setLastInsertId(int lastInsertId){ m_lastInsertId = lastInsertId; };
59 void setErrorDriverText( const std::string &errorDriverText ){ m_errorDriverText = errorDriverText; };
60 void setErrorDatabaseText( const std::string &errorDatabaseText){ m_errorDatabaseText = errorDatabaseText; };
61 stringMapVector *dataPtr(){ return &m_data; };
66 class eMediaDatabase : public sigc::trackable
68 static eMediaDatabase *instance;
69 eMediaScanner *m_scanner;
70 eMediaDatabaseHandler *m_db;
71 std::vector<eFileWatch*> m_watches;
72 std::map<std::string, sigc::connection> m_watchconns;
73 typedef void (eMediaDatabase::*table_line_extension_func)(stringMap *item, QSqlQuery*);
81 static const char FIELD_ID[];
82 static const char FIELD_FILE_ID[];
83 static const char FIELD_DIR_ID[];
84 static const char FIELD_ALBUM_ID[];
85 static const char FIELD_ARTIST_ID[];
86 static const char FIELD_GENRE_ID[];
87 static const char FIELD_CODEC_ID[];
88 static const char FIELD_PATH[];
89 static const char FIELD_FILENAME[];
90 static const char FIELD_SIZE[];
91 static const char FIELD_DURATION[];
92 static const char FIELD_POPULARITY[];
93 static const char FIELD_LASTPLAYPOS[];
94 static const char FIELD_LASTPLAYED[];
95 static const char FIELD_LASTMODIFIED[];
96 static const char FIELD_LASTUPDATED[];
97 static const char FIELD_TITLE[];
98 static const char FIELD_TRACK[];
99 static const char FIELD_TRACKS_TOTAL[];
100 static const char FIELD_DATE[];
101 static const char FIELD_COMMENT[];
102 static const char FIELD_ARTIST[];
103 static const char FIELD_ALBUM[];
104 static const char FIELD_GENRE[];
105 static const char FIELD_CODEC[];
106 static const char FIELD_CODEC_LONG[];
107 static const char FIELD_WIDTH[];
108 static const char FIELD_HEIGHT[];
109 static const char FIELD_FRAMERATE[];
110 static const char FIELD_HD[];
111 static const char FIELD_WIDESCREEN[];
112 static const char FIELD_RECORDING[];
113 static const char FIELD_PLAYLIST_NAME[];
114 static const char FIELD_FILE_URI[];
115 static const char FIELD_POS[];
116 static const char FIELD_DESCRIPTION[];
117 static const char FIELD_SERVICEREFRENCE[];
118 static const char FIELD_TYPE[];
119 static const char FIELD_NAME[];
121 static eMediaDatabase *getInstance();
127 eMediaDatabaseHandler *getDatabaseHandler();
129 void addToDatabase(const std::list<file_metadata> &data);
130 bool _dbAddAudio(const file_data &fmd, const audio_track &at, const audio_metadata &amd);
131 bool _dbAddVideo(const file_data &fmd, const video_data &vt);
133 void onScanStatistics(std::string dir, uint64_t total, uint64_t successful, uint64_t skipped);
134 void onScanFinished(std::string dir, uint64_t total, uint64_t successful, uint64_t skipped);
135 void onInsertFinished(uint64_t success, uint64_t skipped, uint64_t errors, std::list<int> ids);
137 ePtr<eMediaDatabaseResult> resultFromQuery(QSqlQuery* qry, table_line_extension_func extendItem=0);
138 void extendPlaylistItemAttributes(stringMap *item, QSqlQuery *qry);
140 void onProcessEvents(bool finished);
141 void onFileChanged(eFileWatch *watch, eFileEvent event);
144 std::string getCurrentScanPath();
145 std::vector<std::string> *getEnqueuedPaths();
147 void addPath(const std::string &path, bool watch=false);
148 void rescanPath(const std::string &path);
149 bool requestScanStatistics();
150 ePtr<eMediaDatabaseResult> setParentDirectoryWatched(int dir_id, bool watched);
151 ePtr<eMediaDatabaseResult> deleteParentDirectory(int dir_id);
152 ePtr<eMediaDatabaseResult> getParentDirectories();
154 ePtr<eMediaDatabaseResult> filterAudio(const std::string &needle, int limit = -1, int offset = 0);
155 ePtr<eMediaDatabaseResult> filterByAlbum(const std::string &album, int limit = -1, int offset = 0);
156 ePtr<eMediaDatabaseResult> filterByArtistAlbum(const std::string &artist, const std::string &album, int limit = -1, int offset = 0);
157 ePtr<eMediaDatabaseResult> filterByArtist(const std::string &artist, int limit = -1, int offset = 0);
158 ePtr<eMediaDatabaseResult> filterByGenre(const std::string &genre, int limit = -1, int offset = 0);
159 ePtr<eMediaDatabaseResult> filterByTitle(const std::string &title, int limit = -1, int offset = 0);
160 ePtr<eMediaDatabaseResult> getAllArtists(int limit = -1, int offset = 0);
161 ePtr<eMediaDatabaseResult> getArtists(const std::string &artist, int limit = -1, int offset = 0);
162 ePtr<eMediaDatabaseResult> getAllAlbums(int limit = -1, int offset = 0);
163 ePtr<eMediaDatabaseResult> getAlbums(const std::string &album, int limit = -1, int offset = 0);
164 ePtr<eMediaDatabaseResult> getAlbumsByArtist(const std::string &artist, int limit = -1, int offset = 0);
165 ePtr<eMediaDatabaseResult> getAllAudio(int limit = -1, int offset = 0);
166 ePtr<eMediaDatabaseResult> getAllVideos(int limit = -1, int offset = 0);
168 ePtr<eMediaDatabaseResult> addRecording(const std::string &filepath, const std::string & title, int created);
169 ePtr<eMediaDatabaseResult> getAllRecordings(int limit = -1, int offset = 0);
170 ePtr<eMediaDatabaseResult> getRecordings(const std::string &dir, const std::list<std::string> &tags = std::list<std::string>(), int limit = -1, int offset = 0);
171 ePtr<eMediaDatabaseResult> getRecordMeta(int file_id);
172 ePtr<eMediaDatabaseResult> setRecordMeta(int file_id, const std::string & ref, const std::string &name, const std::string &description, const std::string &service_data);
173 ePtr<eMediaDatabaseResult> getRecordEit(int file_id);
174 ePtr<eMediaDatabaseResult> setRecordEit(int file_id, uint8_t eit_raw[]);
176 ePtr<eMediaDatabaseResult> getFileByPath(const std::string &filepath);
178 ePtr<eMediaDatabaseResult> setFileAttribute(int file_id, const std::string &key, const std::string &value);
179 ePtr<eMediaDatabaseResult> deleteFileAttribute(int file_id, const std::string &key);
180 ePtr<eMediaDatabaseResult> getFileAttributes(int file_id);
181 ePtr<eMediaDatabaseResult> getFileAttribute(int file_id, const std::string &key);
183 ePtr<eMediaDatabaseResult> addPlaylist(const std::string &name, int type);
184 ePtr<eMediaDatabaseResult> getPlaylist(int id);
185 ePtr<eMediaDatabaseResult> getPlaylistByName(const std::string &name, int type);
186 ePtr<eMediaDatabaseResult> getPlaylistItemsById(int id);
187 ePtr<eMediaDatabaseResult> getPlaylistItemsByName(const std::string &name, int type=-1);
188 ePtr<eMediaDatabaseResult> getPlaylists(int type=-1);
189 ePtr<eMediaDatabaseResult> addToPlaylistById(int playlist_id, int file_id, int pos);
190 ePtr<eMediaDatabaseResult> addToPlaylistByUri(int playlist_id, const std::string &uri, int pos, const stringMap &attributes);
191 ePtr<eMediaDatabaseResult> updatePlaylistItem(int playlist_id, stringMap item);
192 ePtr<eMediaDatabaseResult> clearPlaylist(int playlist_id);
193 ePtr<eMediaDatabaseResult> savePlaylist(int playlist_id, const std::string &name, int type, const stringMapVector &items);
195 ePtr<eMediaDatabaseResult> removeFile(int file_id);
196 ePtr<eMediaDatabaseResult> query(const std::string &sql, const stringList &values=stringList(), bool rw = false);
198 /* void scanStatistics( std::string, uint64_t, uint64_t, uint64_t ); */
199 eSignal4<void, std::string, uint64_t, uint64_t, uint64_t> scanStatistics;
200 /* void scanFinished( std::string, uint64_t, uint64_t, uint64_t ); */
201 eSignal4<void, std::string, uint64_t, uint64_t, uint64_t> scanFinished;
202 /* void insertFinished(uint64_t, uint64_t, uint64_t, PyObject*); */
203 eSignal4<void, uint64_t, uint64_t, uint64_t, intList > insertFinished;
204 /* void priorityInsertFinished ( char*, uint64_t, uint64_t, uint64_t, int ); */
205 eSignal5<void, const char *, uint64_t, uint64_t, uint64_t, int> priorityInsertFinished;
208 SWIG_TEMPLATE_TYPEDEF(ePtr<eMediaDatabaseResult>, eMediaDatabaseResultPtr);
211 class eMediaDatabaseHandler : public eMainloop_native, public eThread, public sigc::trackable
213 std::string normalizePath(const std::string &path);
216 eMediaDatabaseHandler();
217 ~eMediaDatabaseHandler();
219 static pthread_mutex_t priority_files_lock, files_lock;
221 void insertList(const std::string &dir, std::list<file_metadata> files);
222 void priorityInsert(const file_metadata &file);
228 int addParentDirectory(const std::string &dir, bool watch);
229 bool isParentDirectory(int dir_id);
230 QSqlQuery setParentDirectoryWatched(int dir_id, bool watched);
231 QSqlQuery deleteDirectory(int dir_id);
232 QSqlQuery deleteDirectory(const std::string &dir);
233 QSqlQuery moveDirectory(const std::string &from, const std::string &to);
234 QSqlQuery getParentDirectories();
236 QSqlQuery filterAudio(const std::string &needle, int limit = -1, int offset = 0);
237 QSqlQuery filterByAlbum(const std::string &album, int limit = -1, int offset = 0);
238 QSqlQuery filterByArtistAlbum(const std::string &artist, const std::string &album, int limit = -1, int offset = 0);
239 QSqlQuery filterByArtist(const std::string &artist, int limit = -1, int offset = 0);
240 QSqlQuery filterByGenre(const std::string &genre, int limit = -1, int offset = 0);
241 QSqlQuery filterByTitle(const std::string &title, int limit = -1, int offset = 0);
243 QSqlQuery getAllArtists(int limit = -1, int offset = 0);
244 QSqlQuery getArtists(const std::string &artist, int limit = -1, int offset = 0);
245 QSqlQuery getAllAlbums(int limit = -1, int offset = 0);
246 QSqlQuery getAlbums(const std::string &album, int limit = -1, int offset = 0);
247 QSqlQuery getAlbumsByArtist(const std::string &artist, int limit = -1, int offset = 0);
249 QSqlQuery getAllAudio(int limit = -1, int offset = 0);
250 QSqlQuery getAllVideos(int limit = -1, int offset = 0);
253 QSqlQuery addRecording(const std::string &filepath, const std::string & title, int created);
254 QSqlQuery getAllRecordings(int limit = -1, int offset = 0);
255 QSqlQuery getRecordings(const std::string &dir, const std::list<std::string> &tags = std::list<std::string>(), int limit = -1, int offset = 0);
256 QSqlQuery getRecordMeta(int file_id);
257 QSqlQuery setRecordMeta(int file_id, const std::string & ref, const std::string &name, const std::string &description, const std::string &service_data);
258 QSqlQuery getRecordEit(int file_id);
259 QSqlQuery setRecordEit(int file_id, const uint8_t eit_raw[]);
261 QSqlQuery getByFile(const std::string &filepath);
262 QSqlQuery getAudioByFile(const std::string &filepath);
263 QSqlQuery getVideoByFile(const std::string &filepath);
265 QSqlQuery getById(int id);
266 QSqlQuery getAudioById(int id);
267 QSqlQuery getVideoById(int id);
269 QSqlQuery setFileAttribute(int file_id, const std::string &key, const std::string &value);
270 QSqlQuery deleteFileAttribute(int file_id, const std::string &key);
271 QSqlQuery getFileAttributes(int file_id);
272 QSqlQuery getFileAttribute(int file_id, const std::string &key);
274 QSqlQuery addPlaylist(const std::string &name, int type);
275 QSqlQuery getPlaylistById(int id);
276 QSqlQuery getPlaylistByName(const std::string &name, int type);
277 QSqlQuery getPlaylistItemsById(int id);
278 QSqlQuery getPlaylistItemsByName(const std::string &name, int type);
279 QSqlQuery getPlaylists(int type);
280 QSqlQuery addToPlaylistById(int playlist_id, int file_id, int pos);
281 QSqlQuery addToPlaylistByUri(int playlist_id, const std::string &uri, int pos, const stringMap &attributes=stringMap());
282 void condensePlaylistItemAttributes(stringMap *item);
283 QSqlQuery updatePlaylistItemInternal(int playlist_id, int item_id, int file_id, const std::string &file_uri, int pos, stringMap *attributes);
284 QSqlQuery updatePlaylistItem(int playlist_id, stringMap *attributes);
285 QSqlQuery getPlaylistItemAttribute(int playlist_item_id, const std::string &key);
286 QSqlQuery getPlaylistItemAttributes(int playlist_item_id);
287 QSqlQuery clearPlaylist(int id);
288 QSqlQuery savePlaylist(int playlist_id, const std::string &name, int type, const stringMapVector &items);
290 QSqlQuery removeFile(int file_id);
292 QSqlQuery query(const std::string &sql, const stringList &values=stringList(), bool rw = false);
294 Signal4<void, uint64_t, uint64_t, uint64_t, std::list<int> > insertFinished;
295 Signal5<void, char*, uint64_t, uint64_t, uint64_t, int> priorityInsertFinished;
320 DbMessage(int type=0, char* filename=0, uint64_t errors=0, uint64_t successful=0, uint64_t skipped=0, int file_id=0) :
321 type(type), filename(filename), errors(errors), successful(successful), skipped(skipped), file_id(file_id) {}
324 eFixedMessagePump<DbMessage> m_messages_to_thread;
325 eFixedMessagePump<DbMessage> m_messages_from_thread;
327 bool m_immediate_cancel;
328 int m_dummy; //for sqlite shared cache init;
330 std::list<file_metadata> m_priority_files;
331 std::list<file_metadata> m_files;
332 std::list<int> m_inserted_ids;
333 std::list<std::string> m_directories;
334 std::string m_parent_dir;
337 QSqlDatabase m_db_rw, m_db_ro;
339 QSqlQuery m_qry_insert_file;
340 QSqlQuery m_qry_insert_directory;
341 QSqlQuery m_qry_insert_codec;
342 QSqlQuery m_qry_insert_audio_track;
343 QSqlQuery m_qry_insert_audio_meta;
344 QSqlQuery m_qry_insert_artist;
345 QSqlQuery m_qry_insert_album;
346 QSqlQuery m_qry_insert_genre;
347 QSqlQuery m_qry_insert_video;
348 QSqlQuery m_qry_insert_location;
349 QSqlQuery m_qry_insert_tag;
351 QSqlQuery m_qry_delete_file;
352 QSqlQuery m_qry_update_file;
354 QSqlQuery m_qry_get_file_by_id;
355 QSqlQuery m_qry_get_file_lastmodified;
356 QSqlQuery m_qry_get_directory_by_id;
357 QSqlQuery m_qry_get_directory_by_path;
358 QSqlQuery m_qry_get_codec_by_id;
359 QSqlQuery m_qry_get_codec_by_name;
360 QSqlQuery m_qry_get_audio_tracks_by_file_id;
361 QSqlQuery m_qry_get_audio_meta_by_file_id;
362 QSqlQuery m_qry_get_artist_by_id;
363 QSqlQuery m_qry_get_artist_by_name;
364 QSqlQuery m_qry_get_album_by_id;
365 QSqlQuery m_qry_get_album_by_name;
366 QSqlQuery m_qry_get_genre_by_id;
367 QSqlQuery m_qry_get_genre_by_name;
368 QSqlQuery m_qry_get_video_by_file_id;
369 QSqlQuery m_qry_get_location_by_id;
370 QSqlQuery m_qry_get_tag_by_id;
371 QSqlQuery m_qry_get_tag_by_name;
373 QSqlQuery m_qry_check_file;
374 QSqlQuery m_qry_check_directory;
375 QSqlQuery m_qry_check_codec;
376 QSqlQuery m_qry_check_audio_track;
377 QSqlQuery m_qry_check_artist;
378 QSqlQuery m_qry_check_album;
379 QSqlQuery m_qry_check_genre;
380 QSqlQuery m_qry_check_tag;
382 void processFileLists();
383 insert_result processSingleFile(const file_metadata &fmd, bool has_parent=false);
384 void gotMessage(const DbMessage &message);
386 QString genSelectAllById(const QString &table);
387 QString genSelectAllBySingleField(const QString &table, const QString &field);
388 QString genSelectGetIdSimple(const QString &table, const QString &field);
390 const long long getIdSimple(QSqlQuery *statement, bool clear = true);
391 insert_result insertError(int id=INSERT_ERROR);
392 insert_result insertAndCleanup(QSqlQuery *statement);
394 insert_result getSetDirectory(int parent_id, const std::string &path, bool parent = false, bool watch = false);
395 insert_result getSetFile(int dir_id, const std::string &name, int64_t size, int type, int64_t duration, int64_t lastmodified, int popularity=0, int64_t lastplaypos=0 );
396 int getFileLastModified(int dir_id, const std::string &name, file_data *data);
397 insert_result getSetCodec(const std::string &codec, const std::string &codec_long);
398 insert_result setAudioTrack(int file_id, int codec_id, const std::string &lang);
399 insert_result getSetArtist(const std::string &artist);
400 insert_result getSetAlbum(int artist_id, const std::string &album);
401 insert_result getSetGenre(const std::string &genre);
402 insert_result setAudioMeta(int file_id, int artist_id, int album_artist_id, int album_id, int genre_id, const audio_metadata &amd);
403 insert_result setVideoTrack(int file_id, int codec_id, const video_data &vd);
405 #endif //eDatabaseThread