static void test_query_eval (RhythmDB *db, RhythmDBQuery *query, RhythmDBEntry *entry, gboolean expected, const char *what) { RhythmDBQueryModel *model; RhythmDBQuery *processed; GtkTreeIter iter = {0,}; /* direct evaluation - need to preprocess it first */ processed = rhythmdb_query_copy (query); rhythmdb_query_preprocess (db, processed); fail_unless (rhythmdb_evaluate_query (db, processed, entry) == expected, what); rhythmdb_query_free (processed); /* query evaluation - query is preprocessed by rhythmdb */ model = rhythmdb_query_model_new_empty (db); rhythmdb_do_full_query_parsed (db, RHYTHMDB_QUERY_RESULTS (model), query); fail_unless (rhythmdb_query_model_entry_to_iter (model, entry, &iter) == expected, what); g_object_unref (model); }
static void rebuild_child_model (RBLibraryBrowser *widget, gint property_index, gboolean query_pending) { RBLibraryBrowserPrivate *priv = RB_LIBRARY_BROWSER_GET_PRIVATE (widget); RhythmDBPropertyModel *prop_model; RhythmDBQueryModel *base_model, *child_model; RBPropertyView *view; RhythmDBQuery *query; GList *selections; g_assert (property_index >= 0); g_assert (property_index < num_browser_properties); /* get the query model for the previous property view */ view = g_hash_table_lookup (priv->property_views, (gpointer)browser_properties[property_index].type); prop_model = rb_property_view_get_model (view); g_object_get (prop_model, "query-model", &base_model, NULL); selections = g_hash_table_lookup (priv->selections, (gpointer)browser_properties[property_index].type); if (selections != NULL) { /* create a new query model based on it, filtered by * the selections of the previous property view. * we need the entry type query criteria to allow the * backend to optimise the query. */ query = rhythmdb_query_parse (priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, priv->entry_type, RHYTHMDB_QUERY_END); rhythmdb_query_append_prop_multiple (priv->db, query, browser_properties[property_index].type, selections); child_model = rhythmdb_query_model_new_empty (priv->db); if (query_pending) { rb_debug ("rebuilding child model for browser %d; query is pending", property_index); g_object_set (child_model, "query", query, "base-model", base_model, NULL); } else { rb_debug ("rebuilding child model for browser %d; running new query", property_index); rhythmdb_query_model_chain (child_model, base_model, FALSE); rhythmdb_do_full_query_parsed (priv->db, RHYTHMDB_QUERY_RESULTS (child_model), query); } rhythmdb_query_free (query); } else { rb_debug ("no selection for browser %d - reusing parent model", property_index); child_model = g_object_ref (base_model); } /* If this is the last property, use the child model as the output model * for the browser. Otherwise, use it as the input for the next property * view. */ if (property_index == num_browser_properties-1) { if (priv->output_model != NULL) { g_object_unref (priv->output_model); } priv->output_model = child_model; g_object_notify (G_OBJECT (widget), "output-model"); } else { view = g_hash_table_lookup (priv->property_views, (gpointer)browser_properties[property_index+1].type); ignore_selection_changes (widget, view, TRUE); prop_model = rb_property_view_get_model (view); g_object_set (prop_model, "query-model", child_model, NULL); g_object_unref (child_model); rebuild_child_model (widget, property_index + 1, query_pending); restore_selection (widget, property_index + 1, query_pending); } g_object_unref (base_model); }
static void rb_iradio_source_do_query (RBIRadioSource *source) { RhythmDBQueryModel *genre_query_model = NULL; RhythmDBQueryModel *station_query_model = NULL; RhythmDBPropertyModel *genre_model; GPtrArray *query; RhythmDBEntryType *entry_type; /* don't update the selection while we're rebuilding the query */ source->priv->setting_new_query = TRUE; /* construct and run the query for the search box. * this is used as the model for the genre view. */ g_object_get (source, "entry-type", &entry_type, NULL); query = rhythmdb_query_parse (source->priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type, RHYTHMDB_QUERY_END); g_object_unref (entry_type); if (source->priv->search_query != NULL) { rhythmdb_query_append (source->priv->db, query, RHYTHMDB_QUERY_SUBQUERY, source->priv->search_query, RHYTHMDB_QUERY_END); } genre_model = rb_property_view_get_model (source->priv->genres); genre_query_model = rhythmdb_query_model_new_empty (source->priv->db); g_object_set (genre_model, "query-model", genre_query_model, NULL); rhythmdb_do_full_query_parsed (source->priv->db, RHYTHMDB_QUERY_RESULTS (genre_query_model), query); rhythmdb_query_free (query); query = NULL; /* check the selected genre is still available, and if not, select 'all' */ if (source->priv->selected_genre != NULL) { GList *sel = NULL; if (!rhythmdb_property_model_iter_from_string (genre_model, source->priv->selected_genre, NULL)) { g_free (source->priv->selected_genre); source->priv->selected_genre = NULL; } sel = g_list_prepend (sel, source->priv->selected_genre); rb_property_view_set_selection (source->priv->genres, sel); g_list_free (sel); } /* if a genre is selected, construct a new query for it, and create * a new model based on the search box query model. otherwise, just * reuse the search box query model. */ if (source->priv->selected_genre != NULL) { rb_debug ("matching on genre \"%s\"", source->priv->selected_genre); station_query_model = rhythmdb_query_model_new_empty (source->priv->db); query = rhythmdb_query_parse (source->priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_GENRE, source->priv->selected_genre, RHYTHMDB_QUERY_END); g_object_set (station_query_model, "query", query, "base-model", genre_query_model, NULL); rhythmdb_query_free (query); query = NULL; } else { station_query_model = g_object_ref (genre_query_model); } rb_entry_view_set_model (source->priv->stations, station_query_model); g_object_set (source, "query-model", station_query_model, NULL); g_object_unref (genre_query_model); g_object_unref (station_query_model); source->priv->setting_new_query = FALSE; }