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