2 * arch-tag: Header for RhythmDB - Rhythmbox backend queryable database
4 * Copyright (C) 2003,2004 Colin Walters <walters@rhythmbox.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include <glib-object.h>
28 #include <libxml/tree.h>
31 #include "rb-refstring.h"
32 #include "rhythmdb-query-results.h"
37 typedef struct RhythmDB_ RhythmDB
;
39 #define RHYTHMDB_TYPE (rhythmdb_get_type ())
40 #define RHYTHMDB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RHYTHMDB_TYPE, RhythmDB))
41 #define RHYTHMDB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), RHYTHMDB_TYPE, RhythmDBClass))
42 #define RHYTHMDB_IS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RHYTHMDB_TYPE))
43 #define RHYTHMDB_IS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), RHYTHMDB_TYPE))
44 #define RHYTHMDB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RHYTHMDB_TYPE, RhythmDBClass))
46 struct RhythmDBEntry_
;
47 typedef struct RhythmDBEntry_ RhythmDBEntry
;
48 GType
rhythmdb_entry_get_type (void);
50 #define RHYTHMDB_TYPE_ENTRY (rhythmdb_entry_get_type ())
51 #define RHYTHMDB_ENTRY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RHYTHMDB_TYPE_ENTRY, RhythmDBEntry))
53 typedef void (*RhythmDBEntryActionFunc
) (RhythmDBEntry
*entry
, gpointer data
);
54 typedef char* (*RhythmDBEntryStringFunc
) (RhythmDBEntry
*entry
, gpointer data
);
55 typedef gboolean (*RhythmDBEntryCanSyncFunc
) (RhythmDB
*db
, RhythmDBEntry
*entry
, gpointer data
);
56 typedef void (*RhythmDBEntrySyncFunc
) (RhythmDB
*db
, RhythmDBEntry
*entry
, GError
**error
, gpointer data
);
58 enum RhythmDBEntryCategory
{
59 RHYTHMDB_ENTRY_NORMAL
, /* anything that doesn't match the other categories */
60 RHYTHMDB_ENTRY_STREAM
, /* endless streams (eg shoutcast, last.fm) */
61 RHYTHMDB_ENTRY_CONTAINER
, /* things that point to other entries (eg podcast feeds) */
62 RHYTHMDB_ENTRY_VIRTUAL
/* import errors, ignored files */
68 guint entry_type_data_size
;
69 gboolean save_to_disk
;
70 enum RhythmDBEntryCategory category
;
72 /* virtual functions here */
73 RhythmDBEntryActionFunc post_entry_create
;
74 gpointer post_entry_create_data
;
75 GDestroyNotify post_entry_create_destroy
;
77 RhythmDBEntryActionFunc pre_entry_destroy
;
78 gpointer pre_entry_destroy_data
;
79 GDestroyNotify pre_entry_destroy_destroy
;
81 RhythmDBEntryStringFunc get_playback_uri
;
82 gpointer get_playback_uri_data
;
83 GDestroyNotify get_playback_uri_destroy
;
85 RhythmDBEntryCanSyncFunc can_sync_metadata
;
86 gpointer can_sync_metadata_data
;
87 GDestroyNotify can_sync_metadata_destroy
;
89 RhythmDBEntrySyncFunc sync_metadata
;
90 gpointer sync_metadata_data
;
91 GDestroyNotify sync_metadata_destroy
;
93 typedef RhythmDBEntryType_
*RhythmDBEntryType
;
95 GType
rhythmdb_entry_type_get_type (void);
96 #define RHYTHMDB_TYPE_ENTRY_TYPE (rhythmdb_entry_type_get_type ())
97 #define RHYTHMDB_ENTRY_TYPE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RHYTHMDB_TYPE_ENTRY_TYPE, RhythmDBEntryType_))
98 #define RHYTHMDB_IS_ENTRY_TYPE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RHYTHMDB_TYPE_ENTRY_TYPE))
100 typedef GPtrArray RhythmDBQuery
;
101 GType
rhythmdb_query_get_type (void);
102 #define RHYTHMDB_TYPE_QUERY (rhythmdb_query_get_type ())
103 #define RHYTHMDB_QUERY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), RHYTHMDB_TYPE_QUERY, RhythmDBQuery))
104 #define RHYTHMDB_IS_QUERY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), RHYTHMDB_TYPE_QUERY))
106 #define RHYTHMDB_ENTRY_TYPE_SONG (rhythmdb_entry_song_get_type ())
107 #define RHYTHMDB_ENTRY_TYPE_PODCAST_POST (rhythmdb_entry_podcast_post_get_type ())
108 #define RHYTHMDB_ENTRY_TYPE_PODCAST_FEED (rhythmdb_entry_podcast_feed_get_type ())
109 #define RHYTHMDB_ENTRY_TYPE_IMPORT_ERROR (rhythmdb_entry_import_error_get_type ())
110 #define RHYTHMDB_ENTRY_TYPE_IGNORE (rhythmdb_entry_ignore_get_type ())
111 #define RHYTHMDB_ENTRY_TYPE_INVALID (GINT_TO_POINTER (-1))
116 RHYTHMDB_QUERY_DISJUNCTION
,
117 RHYTHMDB_QUERY_SUBQUERY
,
120 RHYTHMDB_QUERY_PROP_EQUALS
,
123 RHYTHMDB_QUERY_PROP_LIKE
,
124 RHYTHMDB_QUERY_PROP_NOT_LIKE
,
125 RHYTHMDB_QUERY_PROP_PREFIX
,
126 RHYTHMDB_QUERY_PROP_SUFFIX
,
129 RHYTHMDB_QUERY_PROP_GREATER
,
130 RHYTHMDB_QUERY_PROP_LESS
,
132 /* synthetic query types, translated into non-synthetic ones internally */
133 RHYTHMDB_QUERY_PROP_CURRENT_TIME_WITHIN
,
134 RHYTHMDB_QUERY_PROP_CURRENT_TIME_NOT_WITHIN
,
135 RHYTHMDB_QUERY_PROP_YEAR_EQUALS
,
136 RHYTHMDB_QUERY_PROP_YEAR_GREATER
,
137 RHYTHMDB_QUERY_PROP_YEAR_LESS
,
140 /* If you modify this enum, don't forget to modify rhythmdb_prop_get_type */
143 RHYTHMDB_PROP_TYPE
= 0,
144 RHYTHMDB_PROP_ENTRY_ID
,
147 RHYTHMDB_PROP_ARTIST
,
149 RHYTHMDB_PROP_TRACK_NUMBER
,
150 RHYTHMDB_PROP_DISC_NUMBER
,
151 RHYTHMDB_PROP_DURATION
,
152 RHYTHMDB_PROP_FILE_SIZE
,
153 RHYTHMDB_PROP_LOCATION
,
154 RHYTHMDB_PROP_MOUNTPOINT
,
156 RHYTHMDB_PROP_FIRST_SEEN
,
157 RHYTHMDB_PROP_LAST_SEEN
,
158 RHYTHMDB_PROP_RATING
,
159 RHYTHMDB_PROP_PLAY_COUNT
,
160 RHYTHMDB_PROP_LAST_PLAYED
,
161 RHYTHMDB_PROP_BITRATE
,
163 RHYTHMDB_PROP_TRACK_GAIN
,
164 RHYTHMDB_PROP_TRACK_PEAK
,
165 RHYTHMDB_PROP_ALBUM_GAIN
,
166 RHYTHMDB_PROP_ALBUM_PEAK
,
167 RHYTHMDB_PROP_MIMETYPE
,
168 RHYTHMDB_PROP_TITLE_SORT_KEY
,
169 RHYTHMDB_PROP_GENRE_SORT_KEY
,
170 RHYTHMDB_PROP_ARTIST_SORT_KEY
,
171 RHYTHMDB_PROP_ALBUM_SORT_KEY
,
172 RHYTHMDB_PROP_TITLE_FOLDED
,
173 RHYTHMDB_PROP_GENRE_FOLDED
,
174 RHYTHMDB_PROP_ARTIST_FOLDED
,
175 RHYTHMDB_PROP_ALBUM_FOLDED
,
176 RHYTHMDB_PROP_LAST_PLAYED_STR
,
177 RHYTHMDB_PROP_HIDDEN
,
178 RHYTHMDB_PROP_PLAYBACK_ERROR
,
179 RHYTHMDB_PROP_FIRST_SEEN_STR
,
180 RHYTHMDB_PROP_LAST_SEEN_STR
,
182 /* synthetic properties */
183 RHYTHMDB_PROP_SEARCH_MATCH
,
186 /* Podcast properties */
187 RHYTHMDB_PROP_STATUS
,
188 RHYTHMDB_PROP_DESCRIPTION
,
189 RHYTHMDB_PROP_SUBTITLE
,
190 RHYTHMDB_PROP_SUMMARY
,
192 RHYTHMDB_PROP_COPYRIGHT
,
194 RHYTHMDB_PROP_POST_TIME
,
196 RHYTHMDB_PROP_MUSICBRAINZ_TRACKID
,
198 RHYTHMDB_NUM_PROPERTIES
202 RHYTHMDB_PODCAST_STATUS_COMPLETE
= 100,
203 RHYTHMDB_PODCAST_STATUS_ERROR
= 101,
204 RHYTHMDB_PODCAST_STATUS_WAITING
= 102,
205 RHYTHMDB_PODCAST_STATUS_PAUSED
= 103,
208 /* commonly used extra entry metadata */
209 #define RHYTHMDB_PROP_STREAM_SONG_TITLE "rb:stream-song-title"
210 #define RHYTHMDB_PROP_STREAM_SONG_ARTIST "rb:stream-song-artist"
211 #define RHYTHMDB_PROP_STREAM_SONG_ALBUM "rb:stream-song-album"
213 GType
rhythmdb_query_type_get_type (void);
214 GType
rhythmdb_prop_type_get_type (void);
216 #define RHYTHMDB_TYPE_QUERY_TYPE (rhythmdb_query_type_get_type ())
217 #define RHYTHMDB_TYPE_PROP_TYPE (rhythmdb_prop_type_get_type ())
227 RhythmDBPropType prop
;
230 } RhythmDBEntryChange
;
232 const char *rhythmdb_entry_get_string (RhythmDBEntry
*entry
, RhythmDBPropType propid
);
233 RBRefString
*rhythmdb_entry_get_refstring (RhythmDBEntry
*entry
, RhythmDBPropType propid
);
234 char *rhythmdb_entry_dup_string (RhythmDBEntry
*entry
, RhythmDBPropType propid
);
235 gboolean
rhythmdb_entry_get_boolean (RhythmDBEntry
*entry
, RhythmDBPropType propid
);
236 guint64
rhythmdb_entry_get_uint64 (RhythmDBEntry
*entry
, RhythmDBPropType propid
);
237 gulong
rhythmdb_entry_get_ulong (RhythmDBEntry
*entry
, RhythmDBPropType propid
);
238 double rhythmdb_entry_get_double (RhythmDBEntry
*entry
, RhythmDBPropType propid
);
239 gpointer
rhythmdb_entry_get_pointer (RhythmDBEntry
*entry
, RhythmDBPropType propid
);
241 RhythmDBEntryType
rhythmdb_entry_get_entry_type (RhythmDBEntry
*entry
);
245 RHYTHMDB_ERROR_ACCESS_FAILED
,
248 #define RHYTHMDB_ERROR (rhythmdb_error_quark ())
250 GQuark
rhythmdb_error_quark (void);
252 typedef struct RhythmDBPrivate RhythmDBPrivate
;
258 RhythmDBPrivate
*priv
;
266 void (*entry_added
) (RhythmDB
*db
, RhythmDBEntry
*entry
);
267 void (*entry_changed
) (RhythmDB
*db
, RhythmDBEntry
*entry
, GSList
*changes
); /* list of RhythmDBEntryChanges */
268 void (*entry_deleted
) (RhythmDB
*db
, RhythmDBEntry
*entry
);
269 GValue
*(*entry_extra_metadata_request
) (RhythmDB
*db
, RhythmDBEntry
*entry
);
270 void (*entry_extra_metadata_gather
) (RhythmDB
*db
, RhythmDBEntry
*entry
, GHashTable
*data
);
271 void (*entry_extra_metadata_notify
) (RhythmDB
*db
, RhythmDBEntry
*entry
, const char *field
, GValue
*metadata
);
272 void (*load_complete
) (RhythmDB
*db
);
273 void (*save_complete
) (RhythmDB
*db
);
274 void (*load_error
) (RhythmDB
*db
, const char *uri
, const char *msg
);
275 void (*save_error
) (RhythmDB
*db
, const char *uri
, const GError
*error
);
276 void (*read_only
) (RhythmDB
*db
, gboolean readonly
);
278 /* virtual methods */
280 gboolean (*impl_load
) (RhythmDB
*db
, gboolean
*dead
, GError
**error
);
281 void (*impl_save
) (RhythmDB
*db
);
283 void (*impl_entry_new
) (RhythmDB
*db
, RhythmDBEntry
*entry
);
285 gboolean (*impl_entry_set
) (RhythmDB
*db
, RhythmDBEntry
*entry
,
286 guint propid
, const GValue
*value
);
288 void (*impl_entry_get
) (RhythmDB
*db
, RhythmDBEntry
*entry
,
289 guint propid
, GValue
*value
);
291 void (*impl_entry_delete
) (RhythmDB
*db
, RhythmDBEntry
*entry
);
293 void (*impl_entry_delete_by_type
) (RhythmDB
*db
, RhythmDBEntryType type
);
295 RhythmDBEntry
* (*impl_lookup_by_location
)(RhythmDB
*db
, RBRefString
*uri
);
297 gboolean (*impl_evaluate_query
) (RhythmDB
*db
, GPtrArray
*query
, RhythmDBEntry
*entry
);
299 void (*impl_entry_foreach
) (RhythmDB
*db
, GFunc func
, gpointer data
);
301 void (*impl_do_full_query
) (RhythmDB
*db
, GPtrArray
*query
,
302 RhythmDBQueryResults
*results
,
305 void (*impl_entry_type_registered
) (RhythmDB
*db
,
307 RhythmDBEntryType type
);
310 GType
rhythmdb_get_type (void);
312 RhythmDB
* rhythmdb_new (const char *name
);
314 void rhythmdb_shutdown (RhythmDB
*db
);
316 void rhythmdb_load (RhythmDB
*db
);
318 void rhythmdb_save (RhythmDB
*db
);
319 void rhythmdb_save_async (RhythmDB
*db
);
321 void rhythmdb_start_action_thread (RhythmDB
*db
);
323 void rhythmdb_commit (RhythmDB
*db
);
325 gboolean
rhythmdb_entry_is_editable (RhythmDB
*db
, RhythmDBEntry
*entry
);
327 RhythmDBEntry
* rhythmdb_entry_new (RhythmDB
*db
, RhythmDBEntryType type
, const char *uri
);
328 RhythmDBEntry
* rhythmdb_entry_example_new (RhythmDB
*db
, RhythmDBEntryType type
, const char *uri
);
330 void rhythmdb_add_uri (RhythmDB
*db
, const char *uri
);
331 void rhythmdb_add_uri_with_type (RhythmDB
*db
, const char *uri
, RhythmDBEntryType type
);
333 void rhythmdb_entry_get (RhythmDB
*db
, RhythmDBEntry
*entry
, RhythmDBPropType propid
, GValue
*val
);
334 void rhythmdb_entry_set (RhythmDB
*db
, RhythmDBEntry
*entry
,
335 guint propid
, const GValue
*value
);
337 char * rhythmdb_entry_get_playback_uri (RhythmDBEntry
*entry
);
339 gpointer
rhythmdb_entry_get_type_data (RhythmDBEntry
*entry
, guint expected_size
);
340 #define RHYTHMDB_ENTRY_GET_TYPE_DATA(e,t) ((t*)rhythmdb_entry_get_type_data((e),sizeof(t)))
342 void rhythmdb_entry_delete (RhythmDB
*db
, RhythmDBEntry
*entry
);
343 void rhythmdb_entry_delete_by_type (RhythmDB
*db
,
344 RhythmDBEntryType type
);
345 void rhythmdb_entry_move_to_trash (RhythmDB
*db
,
346 RhythmDBEntry
*entry
);
348 RhythmDBEntry
* rhythmdb_entry_lookup_by_location (RhythmDB
*db
, const char *uri
);
350 gboolean
rhythmdb_evaluate_query (RhythmDB
*db
, GPtrArray
*query
,
351 RhythmDBEntry
*entry
);
353 void rhythmdb_entry_foreach (RhythmDB
*db
,
358 * Returns a freshly allocated GtkTreeModel which represents the query.
359 * The extended arguments alternate between RhythmDBQueryType args
360 * and their values. Items are prioritized like algebraic expressions, and
361 * implicitly ANDed. Here's an example:
363 rhythmdb_do_full_query (db,
364 RHYTHMDB_QUERY_PROP_EQUALS,
365 RHYTHMDB_PROP_ARTIST, "Pink Floyd",
366 RHYTHMDB_QUERY_DISJUNCTION,
367 RHYTHMDB_QUERY_PROP_EQUALS,
368 RHYTHMDB_PROP_GENRE, "Classical",
369 RHYTHMDB_QUERY_PROP_GREATER,
370 RHYTHMDB_PROP_RATING, 5,
372 * Which means: artist = Pink Floyd OR (genre = Classical AND rating >= 5)
374 void rhythmdb_do_full_query (RhythmDB
*db
,
375 RhythmDBQueryResults
*results
,
377 void rhythmdb_do_full_query_parsed (RhythmDB
*db
,
378 RhythmDBQueryResults
*results
,
381 void rhythmdb_do_full_query_async (RhythmDB
*db
,
382 RhythmDBQueryResults
*results
,
385 void rhythmdb_do_full_query_async_parsed (RhythmDB
*db
,
386 RhythmDBQueryResults
*results
,
389 GPtrArray
* rhythmdb_query_parse (RhythmDB
*db
, ...);
390 void rhythmdb_query_append (RhythmDB
*db
, GPtrArray
*query
, ...);
391 void rhythmdb_query_append_prop_multiple (RhythmDB
*db
, GPtrArray
*query
, RhythmDBPropType propid
, GList
*items
);
392 void rhythmdb_query_concatenate (GPtrArray
*query1
, GPtrArray
*query2
);
393 void rhythmdb_query_free (GPtrArray
*query
);
394 GPtrArray
* rhythmdb_query_copy (GPtrArray
*array
);
395 void rhythmdb_query_preprocess (RhythmDB
*db
, GPtrArray
*query
);
397 void rhythmdb_query_serialize (RhythmDB
*db
, GPtrArray
*query
,
400 GPtrArray
* rhythmdb_query_deserialize (RhythmDB
*db
, xmlNodePtr node
);
402 char * rhythmdb_query_to_string (RhythmDB
*db
, GPtrArray
*query
);
404 gboolean
rhythmdb_query_is_time_relative (RhythmDB
*db
, GPtrArray
*query
);
406 const xmlChar
* rhythmdb_nice_elt_name_from_propid (RhythmDB
*db
, RhythmDBPropType propid
);
407 int rhythmdb_propid_from_nice_elt_name (RhythmDB
*db
, const xmlChar
*name
);
409 void rhythmdb_emit_entry_added (RhythmDB
*db
, RhythmDBEntry
*entry
);
410 void rhythmdb_emit_entry_deleted (RhythmDB
*db
, RhythmDBEntry
*entry
);
412 GValue
* rhythmdb_entry_request_extra_metadata (RhythmDB
*db
, RhythmDBEntry
*entry
, const gchar
*property_name
);
413 GHashTable
* rhythmdb_entry_gather_metadata (RhythmDB
*db
, RhythmDBEntry
*entry
);
414 void rhythmdb_emit_entry_extra_metadata_notify (RhythmDB
*db
, RhythmDBEntry
*entry
, const gchar
*property_name
, const GValue
*metadata
);
416 gboolean
rhythmdb_is_busy (RhythmDB
*db
);
417 char * rhythmdb_compute_status_normal (gint n_songs
, glong duration
,
419 const char *singular
,
422 RhythmDBEntryType
rhythmdb_entry_register_type (RhythmDB
*db
, const char *name
);
423 RhythmDBEntryType
rhythmdb_entry_type_get_by_name (RhythmDB
*db
, const char *name
);
425 RhythmDBEntryType
rhythmdb_entry_song_get_type (void);
426 RhythmDBEntryType
rhythmdb_entry_podcast_post_get_type (void);
427 RhythmDBEntryType
rhythmdb_entry_podcast_feed_get_type (void);
428 RhythmDBEntryType
rhythmdb_entry_import_error_get_type (void);
429 RhythmDBEntryType
rhythmdb_entry_ignore_get_type (void);
431 GType
rhythmdb_get_property_type (RhythmDB
*db
, guint property_id
);
433 RhythmDBEntry
* rhythmdb_entry_ref (RhythmDBEntry
*entry
);
434 void rhythmdb_entry_unref (RhythmDBEntry
*entry
);
438 #endif /* __RHYTHMBDB_H */