1 /*
2  *  Copyright (C) 2003,2004 Colin Walters <walters@rhythmbox.org>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  The Rhythmbox authors hereby grant permission for non-GPL compatible
10  *  GStreamer plugins to be used and distributed together with GStreamer
11  *  and Rhythmbox. This permission is above and beyond the permissions granted
12  *  by the GPL license by which Rhythmbox is covered. If you modify this code
13  *  you may extend this exception to your version of the code, but you are not
14  *  obligated to do so. If you do not wish to do so, delete this exception
15  *  statement from your version.
16  *
17  *  This program is distributed in the hope that it will be useful,
18  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  *  GNU General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License
23  *  along with this program; if not, write to the Free Software
24  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA.
25  *
26  */
27 
28 #ifndef RHYTHMDB_H
29 #define RHYTHMDB_H
30 
31 #include <glib.h>
32 #include <glib-object.h>
33 #include <gio/gio.h>
34 #include <stdarg.h>
35 #include <libxml/tree.h>
36 
37 #include <rhythmdb/rb-refstring.h>
38 #include <lib/rb-string-value-map.h>
39 #include <rhythmdb/rhythmdb-entry.h>
40 #include <rhythmdb/rhythmdb-entry-type.h>
41 #include <rhythmdb/rhythmdb-query-results.h>
42 #include <metadata/rb-ext-db-key.h>
43 
44 G_BEGIN_DECLS
45 
46 typedef struct _RhythmDB RhythmDB;
47 typedef struct _RhythmDBClass RhythmDBClass;
48 
49 #define RHYTHMDB_TYPE      (rhythmdb_get_type ())
50 #define RHYTHMDB(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RHYTHMDB_TYPE, RhythmDB))
51 #define RHYTHMDB_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), RHYTHMDB_TYPE, RhythmDBClass))
52 #define RHYTHMDB_IS(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RHYTHMDB_TYPE))
53 #define RHYTHMDB_IS_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), RHYTHMDB_TYPE))
54 #define RHYTHMDB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RHYTHMDB_TYPE, RhythmDBClass))
55 
56 
57 typedef GPtrArray RhythmDBQuery;
58 GType rhythmdb_query_get_type (void);
59 #define RHYTHMDB_TYPE_QUERY	(rhythmdb_query_get_type ())
60 #define RHYTHMDB_QUERY(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), RHYTHMDB_TYPE_QUERY, RhythmDBQuery))
61 #define RHYTHMDB_IS_QUERY(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), RHYTHMDB_TYPE_QUERY))
62 
63 typedef enum
64 {
65 	RHYTHMDB_QUERY_END,
66 	RHYTHMDB_QUERY_DISJUNCTION,
67 	RHYTHMDB_QUERY_SUBQUERY,
68 
69 	/* general */
70 	RHYTHMDB_QUERY_PROP_EQUALS,
71 	RHYTHMDB_QUERY_PROP_NOT_EQUAL,
72 
73 	/* string */
74 	RHYTHMDB_QUERY_PROP_LIKE,
75 	RHYTHMDB_QUERY_PROP_NOT_LIKE,
76 	RHYTHMDB_QUERY_PROP_PREFIX,
77 	RHYTHMDB_QUERY_PROP_SUFFIX,
78 
79 	/* numerical */
80 	RHYTHMDB_QUERY_PROP_GREATER,
81 	RHYTHMDB_QUERY_PROP_LESS,
82 
83 	/* synthetic query types, translated into non-synthetic ones internally */
84 	RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN,
85 	RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN,
86 	RHYTHMDB_QUERY_PROP_YEAR_EQUALS,
87 	RHYTHMDB_QUERY_PROP_YEAR_NOT_EQUAL,
88 	RHYTHMDB_QUERY_PROP_YEAR_GREATER,
89 	RHYTHMDB_QUERY_PROP_YEAR_LESS,
90 } RhythmDBQueryType;
91 
92 /* If you modify this enum, don't forget to modify rhythmdb_prop_get_type */
93 typedef enum
94 {
95 	RHYTHMDB_PROP_TYPE = 0,
96 	RHYTHMDB_PROP_ENTRY_ID,
97 	RHYTHMDB_PROP_TITLE,
98 	RHYTHMDB_PROP_GENRE,
99 	RHYTHMDB_PROP_ARTIST,
100 	RHYTHMDB_PROP_ALBUM,
101 	RHYTHMDB_PROP_TRACK_NUMBER,
102 	RHYTHMDB_PROP_TRACK_TOTAL,
103 	RHYTHMDB_PROP_DISC_NUMBER,
104 	RHYTHMDB_PROP_DISC_TOTAL,
105 	RHYTHMDB_PROP_DURATION,
106 	RHYTHMDB_PROP_FILE_SIZE,
107 	RHYTHMDB_PROP_LOCATION,
108 	RHYTHMDB_PROP_MOUNTPOINT,
109 	RHYTHMDB_PROP_MTIME,
110 	RHYTHMDB_PROP_FIRST_SEEN,
111 	RHYTHMDB_PROP_LAST_SEEN,
112 	RHYTHMDB_PROP_RATING,
113 	RHYTHMDB_PROP_PLAY_COUNT,
114 	RHYTHMDB_PROP_LAST_PLAYED,
115 	RHYTHMDB_PROP_BITRATE,
116 	RHYTHMDB_PROP_DATE,
117 	RHYTHMDB_PROP_TRACK_GAIN,			/* obsolete */
118 	RHYTHMDB_PROP_TRACK_PEAK,			/* obsolete */
119 	RHYTHMDB_PROP_ALBUM_GAIN,			/* obsolete */
120 	RHYTHMDB_PROP_ALBUM_PEAK,			/* obsolete */
121 	RHYTHMDB_PROP_MEDIA_TYPE,
122 	RHYTHMDB_PROP_TITLE_SORT_KEY,
123 	RHYTHMDB_PROP_GENRE_SORT_KEY,
124 	RHYTHMDB_PROP_ARTIST_SORT_KEY,
125 	RHYTHMDB_PROP_ALBUM_SORT_KEY,
126 	RHYTHMDB_PROP_TITLE_FOLDED,
127 	RHYTHMDB_PROP_GENRE_FOLDED,
128 	RHYTHMDB_PROP_ARTIST_FOLDED,
129 	RHYTHMDB_PROP_ALBUM_FOLDED,
130 	RHYTHMDB_PROP_LAST_PLAYED_STR,
131 	RHYTHMDB_PROP_HIDDEN,
132 	RHYTHMDB_PROP_PLAYBACK_ERROR,
133 	RHYTHMDB_PROP_FIRST_SEEN_STR,
134 	RHYTHMDB_PROP_LAST_SEEN_STR,
135 
136 	/* synthetic properties */
137 	RHYTHMDB_PROP_SEARCH_MATCH,
138 	RHYTHMDB_PROP_YEAR,
139 	RHYTHMDB_PROP_KEYWORD, /**/
140 
141 	/* Podcast properties */
142 	RHYTHMDB_PROP_STATUS,
143 	RHYTHMDB_PROP_DESCRIPTION,
144 	RHYTHMDB_PROP_SUBTITLE,
145 	RHYTHMDB_PROP_SUMMARY,
146 	RHYTHMDB_PROP_LANG,
147 	RHYTHMDB_PROP_COPYRIGHT,
148 	RHYTHMDB_PROP_IMAGE,
149 	RHYTHMDB_PROP_POST_TIME,
150 
151 	RHYTHMDB_PROP_MUSICBRAINZ_TRACKID,
152 	RHYTHMDB_PROP_MUSICBRAINZ_ARTISTID,
153 	RHYTHMDB_PROP_MUSICBRAINZ_ALBUMID,
154 	RHYTHMDB_PROP_MUSICBRAINZ_ALBUMARTISTID,
155 	RHYTHMDB_PROP_ARTIST_SORTNAME,
156 	RHYTHMDB_PROP_ALBUM_SORTNAME,
157 
158 	RHYTHMDB_PROP_ARTIST_SORTNAME_SORT_KEY,
159 	RHYTHMDB_PROP_ARTIST_SORTNAME_FOLDED,
160 	RHYTHMDB_PROP_ALBUM_SORTNAME_SORT_KEY,
161 	RHYTHMDB_PROP_ALBUM_SORTNAME_FOLDED,
162 
163 	RHYTHMDB_PROP_COMMENT,
164 	RHYTHMDB_PROP_ALBUM_ARTIST,
165 	RHYTHMDB_PROP_ALBUM_ARTIST_SORT_KEY,
166 	RHYTHMDB_PROP_ALBUM_ARTIST_FOLDED,
167 	RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME,
168 	RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_SORT_KEY,
169 	RHYTHMDB_PROP_ALBUM_ARTIST_SORTNAME_FOLDED,
170 	RHYTHMDB_PROP_BPM,
171 
172 	RHYTHMDB_PROP_COMPOSER,
173 	RHYTHMDB_PROP_COMPOSER_SORT_KEY,
174 	RHYTHMDB_PROP_COMPOSER_FOLDED,
175 	RHYTHMDB_PROP_COMPOSER_SORTNAME,
176 	RHYTHMDB_PROP_COMPOSER_SORTNAME_SORT_KEY,
177 	RHYTHMDB_PROP_COMPOSER_SORTNAME_FOLDED,
178 
179 	RHYTHMDB_NUM_PROPERTIES
180 } RhythmDBPropType;
181 
182 enum {
183 	RHYTHMDB_PODCAST_FEED_STATUS_HIDDEN = 0,
184 	RHYTHMDB_PODCAST_FEED_STATUS_NORMAL = 1,
185 	RHYTHMDB_PODCAST_FEED_STATUS_UPDATING = 2,
186 
187 	RHYTHMDB_PODCAST_STATUS_COMPLETE = 100,
188 	RHYTHMDB_PODCAST_STATUS_ERROR = 101,
189 	RHYTHMDB_PODCAST_STATUS_WAITING = 102,
190 	RHYTHMDB_PODCAST_STATUS_PAUSED = 103,
191 };
192 
193 /* commonly used extra entry metadata */
194 #define RHYTHMDB_PROP_STREAM_SONG_TITLE		"rb:stream-song-title"
195 #define RHYTHMDB_PROP_STREAM_SONG_ARTIST	"rb:stream-song-artist"
196 #define RHYTHMDB_PROP_STREAM_SONG_ALBUM		"rb:stream-song-album"
197 #define RHYTHMDB_PROP_COVER_ART			"rb:coverArt"
198 #define RHYTHMDB_PROP_COVER_ART_URI		"rb:coverArt-uri"
199 
200 typedef void (*RhythmDBEntryForeachFunc) (RhythmDBEntry *entry, gpointer data);
201 
202 GType rhythmdb_query_type_get_type (void);
203 GType rhythmdb_prop_type_get_type (void);
204 
205 #define RHYTHMDB_TYPE_QUERY_TYPE (rhythmdb_query_type_get_type ())
206 #define RHYTHMDB_TYPE_PROP_TYPE (rhythmdb_prop_type_get_type ())
207 
208 typedef struct {
209 	guint type;
210 	guint propid;
211 	GValue *val;
212 	RhythmDBQuery *subquery;
213 } RhythmDBQueryData;
214 
215 GType rhythmdb_entry_change_get_type (void);
216 #define RHYTHMDB_TYPE_ENTRY_CHANGE (rhythmdb_entry_change_get_type ())
217 
218 typedef struct {
219 	RhythmDBPropType prop;
220 	GValue old;
221 	GValue new;
222 } RhythmDBEntryChange;
223 
224 const char *rhythmdb_entry_get_string	(RhythmDBEntry *entry, RhythmDBPropType propid);
225 RBRefString *rhythmdb_entry_get_refstring (RhythmDBEntry *entry, RhythmDBPropType propid);
226 char *rhythmdb_entry_dup_string	(RhythmDBEntry *entry, RhythmDBPropType propid);
227 gboolean rhythmdb_entry_get_boolean	(RhythmDBEntry *entry, RhythmDBPropType propid);
228 guint64 rhythmdb_entry_get_uint64	(RhythmDBEntry *entry, RhythmDBPropType propid);
229 gulong rhythmdb_entry_get_ulong		(RhythmDBEntry *entry, RhythmDBPropType propid);
230 double rhythmdb_entry_get_double	(RhythmDBEntry *entry, RhythmDBPropType propid);
231 GObject *rhythmdb_entry_get_object     (RhythmDBEntry *entry, RhythmDBPropType propid);
232 
233 RhythmDBEntryType *rhythmdb_entry_get_entry_type (RhythmDBEntry *entry);
234 
235 typedef enum
236 {
237 	RHYTHMDB_ERROR_ACCESS_FAILED,
238 } RhythmDBError;
239 
240 #define RHYTHMDB_ERROR (rhythmdb_error_quark ())
241 
242 GQuark rhythmdb_error_quark (void);
243 
244 typedef struct _RhythmDBPrivate RhythmDBPrivate;
245 
246 struct _RhythmDB
247 {
248 	GObject parent;
249 
250 	RhythmDBPrivate *priv;
251 };
252 
253 struct _RhythmDBClass
254 {
255 	GObjectClass parent;
256 
257 	/* signals */
258 	void	(*entry_added)		(RhythmDB *db, RhythmDBEntry *entry);
259 	void	(*entry_changed)	(RhythmDB *db, RhythmDBEntry *entry, GArray *changes); /* array of RhythmDBEntryChanges */
260 	void	(*entry_deleted)	(RhythmDB *db, RhythmDBEntry *entry);
261 	void	(*entry_keyword_added)	(RhythmDB *db, RhythmDBEntry *entry, RBRefString *keyword);
262 	void	(*entry_keyword_removed)(RhythmDB *db, RhythmDBEntry *entry, RBRefString *keyword);
263 	GValue *(*entry_extra_metadata_request) (RhythmDB *db, RhythmDBEntry *entry);
264 	void    (*entry_extra_metadata_gather) (RhythmDB *db, RhythmDBEntry *entry, RBStringValueMap *data);
265 	void	(*entry_extra_metadata_notify) (RhythmDB *db, RhythmDBEntry *entry, const char *field, GValue *metadata);
266 	void	(*load_complete)	(RhythmDB *db);
267 	void	(*save_complete)	(RhythmDB *db);
268 	void	(*load_error)		(RhythmDB *db, const char *uri, const char *msg);
269 	void	(*save_error)		(RhythmDB *db, const char *uri, const GError *error);
270 	void	(*read_only)		(RhythmDB *db, gboolean readonly);
271 
272 	/* virtual methods */
273 
274 	gboolean	(*impl_load)		(RhythmDB *db, GCancellable *cancel, GError **error);
275 	void		(*impl_save)		(RhythmDB *db);
276 
277 	void		(*impl_entry_new)	(RhythmDB *db, RhythmDBEntry *entry);
278 
279 	gboolean	(*impl_entry_set)	(RhythmDB *db, RhythmDBEntry *entry,
280 	                                 guint propid, const GValue *value);
281 
282 	void		(*impl_entry_get)	(RhythmDB *db, RhythmDBEntry *entry,
283 						 guint propid, GValue *value);
284 
285 	void		(*impl_entry_delete)	(RhythmDB *db, RhythmDBEntry *entry);
286 
287 	void            (*impl_entry_delete_by_type) (RhythmDB *db, RhythmDBEntryType *type);
288 
289 	RhythmDBEntry *	(*impl_lookup_by_location)(RhythmDB *db, RBRefString *uri);
290 
291 	RhythmDBEntry *	(*impl_lookup_by_id)    (RhythmDB *db, gint id);
292 
293 	gboolean 	(*impl_evaluate_query)	(RhythmDB *db, RhythmDBQuery *query, RhythmDBEntry *entry);
294 
295 	void		(*impl_entry_foreach)	(RhythmDB *db, RhythmDBEntryForeachFunc func, gpointer data);
296 
297 	gint64		(*impl_entry_count)	(RhythmDB *db);
298 
299 	void		(*impl_entry_foreach_by_type) (RhythmDB *db, RhythmDBEntryType *type, RhythmDBEntryForeachFunc func, gpointer data);
300 
301 	gint64		(*impl_entry_count_by_type) (RhythmDB *db, RhythmDBEntryType *type);
302 
303 	void		(*impl_do_full_query)	(RhythmDB *db, RhythmDBQuery *query,
304 						 RhythmDBQueryResults *results,
305 						 gboolean *cancel);
306 
307 	void		(*impl_entry_type_registered) (RhythmDB *db,
308 						       RhythmDBEntryType *type);
309 
310 	gboolean	(*impl_entry_keyword_add)	(RhythmDB *db,
311 							 RhythmDBEntry *entry,
312 							 RBRefString *keyword);
313 	gboolean	(*impl_entry_keyword_remove)	(RhythmDB *db,
314 							 RhythmDBEntry *entry,
315 							 RBRefString *keyword);
316 	gboolean	(*impl_entry_keyword_has)	(RhythmDB *db,
317 							 RhythmDBEntry *entry,
318 							 RBRefString *keyword);
319 	GList*		(*impl_entry_keywords_get)	(RhythmDB *db,
320 							 RhythmDBEntry *entry);
321 };
322 
323 GType		rhythmdb_get_type	(void);
324 
325 void		rhythmdb_shutdown	(RhythmDB *db);
326 
327 void		rhythmdb_load		(RhythmDB *db);
328 
329 void		rhythmdb_save		(RhythmDB *db);
330 void		rhythmdb_save_async	(RhythmDB *db);
331 
332 void		rhythmdb_start_action_thread	(RhythmDB *db);
333 
334 void		rhythmdb_commit		(RhythmDB *db);
335 
336 RhythmDBEntry *	rhythmdb_entry_new	(RhythmDB *db, RhythmDBEntryType *type, const char *uri);
337 RhythmDBEntry *	rhythmdb_entry_example_new	(RhythmDB *db, RhythmDBEntryType *type, const char *uri);
338 
339 void		rhythmdb_add_uri	(RhythmDB *db, const char *uri);		/* <-- die */
340 void		rhythmdb_add_uri_with_types (RhythmDB *db,
341 					     const char *uri,
342 					     RhythmDBEntryType *type,
343 					     RhythmDBEntryType *ignore_type,
344 					     RhythmDBEntryType *error_type);
345 
346 void		rhythmdb_entry_get	(RhythmDB *db, RhythmDBEntry *entry, RhythmDBPropType propid, GValue *val);
347 void		rhythmdb_entry_set	(RhythmDB *db, RhythmDBEntry *entry,
348 					 guint propid, const GValue *value);
349 
350 gboolean	rhythmdb_entry_is_lossless (RhythmDBEntry *entry);
351 
352 gpointer	rhythmdb_entry_get_type_data (RhythmDBEntry *entry, guint expected_size);
353 #define		RHYTHMDB_ENTRY_GET_TYPE_DATA(e,t)	((t*)rhythmdb_entry_get_type_data((e),sizeof(t)))
354 
355 void		rhythmdb_entry_delete	(RhythmDB *db, RhythmDBEntry *entry);
356 void            rhythmdb_entry_delete_by_type (RhythmDB *db,
357 					       RhythmDBEntryType *type);
358 void		rhythmdb_entry_move_to_trash (RhythmDB *db,
359 					      RhythmDBEntry *entry);
360 
361 RhythmDBEntry *	rhythmdb_entry_lookup_by_location (RhythmDB *db, const char *uri);
362 
363 RhythmDBEntry *	rhythmdb_entry_lookup_by_id     (RhythmDB *db, gint id);
364 
365 RhythmDBEntry * rhythmdb_entry_lookup_from_string (RhythmDB *db, const char *str, gboolean is_id);
366 
367 gboolean	rhythmdb_evaluate_query		(RhythmDB *db, RhythmDBQuery *query,
368 						 RhythmDBEntry *entry);
369 
370 void		rhythmdb_entry_foreach		(RhythmDB *db,
371 						 RhythmDBEntryForeachFunc func,
372 						 gpointer data);
373 gint64		rhythmdb_entry_count		(RhythmDB *db);
374 
375 void		rhythmdb_entry_foreach_by_type  (RhythmDB *db,
376 						 RhythmDBEntryType *entry_type,
377 						 RhythmDBEntryForeachFunc func,
378 						 gpointer data);
379 gint64		rhythmdb_entry_count_by_type	(RhythmDB *db,
380 						 RhythmDBEntryType *entry_type);
381 
382 gboolean	rhythmdb_entry_keyword_add	(RhythmDB *db,
383 						 RhythmDBEntry *entry,
384 						 RBRefString *keyword);
385 gboolean	rhythmdb_entry_keyword_remove	(RhythmDB *db,
386 						 RhythmDBEntry *entry,
387 						 RBRefString *keyword);
388 gboolean	rhythmdb_entry_keyword_has	(RhythmDB *db,
389 						 RhythmDBEntry *entry,
390 						 RBRefString *keyword);
391 GList* /*<RBRefString>*/ rhythmdb_entry_keywords_get	(RhythmDB *db,
392 							 RhythmDBEntry *entry);
393 
394 void		rhythmdb_entry_write_metadata_changes (RhythmDB *db,
395 						 RhythmDBEntry *entry,
396 						 GSList *changes,
397 						 GError **error);
398 
399 RBExtDBKey *	rhythmdb_entry_create_ext_db_key (RhythmDBEntry *entry,
400 						 RhythmDBPropType prop);
401 gboolean	rhythmdb_entry_matches_ext_db_key (RhythmDB *db,
402 						 RhythmDBEntry *entry,
403 						 RBExtDBKey *key);
404 
405 /*
406  * Returns a freshly allocated GtkTreeModel which represents the query.
407  * The extended arguments alternate between RhythmDBQueryType args
408  * and their values. Items are prioritized like algebraic expressions, and
409  * implicitly ANDed. Here's an example:
410  *
411 rhythmdb_do_full_query (db,
412 			RHYTHMDB_QUERY_PROP_EQUALS,
413  				RHYTHMDB_PROP_ARTIST, "Pink Floyd",
414 		RHYTHMDB_QUERY_DISJUNCTION,
415 			RHYTHMDB_QUERY_PROP_EQUALS,
416 				RHYTHMDB_PROP_GENRE, "Classical",
417 			RHYTHMDB_QUERY_PROP_GREATER,
418 				RHYTHMDB_PROP_RATING, 5,
419 	RHYTHMDB_QUERY_END);
420  * Which means: artist = Pink Floyd OR (genre = Classical AND rating >= 5)
421  */
422 void		rhythmdb_do_full_query			(RhythmDB *db,
423 							 RhythmDBQueryResults *results,
424 							 ...);
425 void		rhythmdb_do_full_query_parsed		(RhythmDB *db,
426 							 RhythmDBQueryResults *results,
427 							 RhythmDBQuery *query);
428 
429 void		rhythmdb_do_full_query_async		(RhythmDB *db,
430 							 RhythmDBQueryResults *results,
431 							 ...);
432 
433 void		rhythmdb_do_full_query_async_parsed	(RhythmDB *db,
434 							 RhythmDBQueryResults *results,
435 							 RhythmDBQuery *query);
436 
437 RhythmDBQuery *	rhythmdb_query_parse			(RhythmDB *db, ...);
438 void		rhythmdb_query_append			(RhythmDB *db, RhythmDBQuery *query, ...);
439 void		rhythmdb_query_append_params		(RhythmDB *db, RhythmDBQuery *query, RhythmDBQueryType type, RhythmDBPropType prop, const GValue *value);
440 void		rhythmdb_query_append_prop_multiple	(RhythmDB *db, RhythmDBQuery *query, RhythmDBPropType propid, GList *items);
441 void		rhythmdb_query_concatenate		(RhythmDBQuery *query1, RhythmDBQuery *query2);
442 void		rhythmdb_query_free			(RhythmDBQuery *query);
443 RhythmDBQuery *	rhythmdb_query_copy			(RhythmDBQuery *array);
444 void		rhythmdb_query_preprocess		(RhythmDB *db, RhythmDBQuery *query);
445 
446 void		rhythmdb_query_serialize		(RhythmDB *db, RhythmDBQuery *query,
447 							 xmlNodePtr parent);
448 
449 RhythmDBQuery *	rhythmdb_query_deserialize		(RhythmDB *db, xmlNodePtr parent);
450 
451 char *		rhythmdb_query_to_string		(RhythmDB *db, RhythmDBQuery *query);
452 
453 gboolean	rhythmdb_query_is_time_relative		(RhythmDB *db, RhythmDBQuery *query);
454 
455 const xmlChar *	rhythmdb_nice_elt_name_from_propid	(RhythmDB *db, RhythmDBPropType propid);
456 int		rhythmdb_propid_from_nice_elt_name	(RhythmDB *db, const xmlChar *name);
457 
458 void		rhythmdb_emit_entry_added		(RhythmDB *db, RhythmDBEntry *entry);
459 void		rhythmdb_emit_entry_deleted		(RhythmDB *db, RhythmDBEntry *entry);
460 
461 GValue *	rhythmdb_entry_request_extra_metadata	(RhythmDB *db, RhythmDBEntry *entry, const gchar *property_name);
462 RBStringValueMap* rhythmdb_entry_gather_metadata	(RhythmDB *db, RhythmDBEntry *entry);
463 void		rhythmdb_emit_entry_extra_metadata_notify (RhythmDB *db, RhythmDBEntry *entry, const gchar *property_name, const GValue *metadata);
464 
465 char *		rhythmdb_compute_status_normal		(gint n_songs, glong duration,
466 							 guint64 size,
467 							 const char *singular,
468 							 const char *plural);
469 
470 void		rhythmdb_register_entry_type		(RhythmDB *db, RhythmDBEntryType *entry_type);
471 RhythmDBEntryType *rhythmdb_entry_type_get_by_name      (RhythmDB *db, const char *name);
472 
473 GType rhythmdb_get_property_type (RhythmDB *db, guint property_id);
474 
475 RhythmDBEntry* rhythmdb_entry_ref (RhythmDBEntry *entry);
476 void rhythmdb_entry_unref (RhythmDBEntry *entry);
477 
478 G_END_DECLS
479 
480 #endif /* __RHYTHMBDB_H */
481