2 * Copyright (C) 2009, 2010 Jens Georg <mail@jensge.org>.
3 * Copyright (C) 2012, 2013 Intel Corporation.
5 * This file is part of Rygel.
7 * Rygel is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * Rygel is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this program; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "rygel-media-export-errors.h"
23 #include "rygel-media-export-query-container.h"
26 rygel_media_export_query_container_rygel_searchable_container_interface_init (RygelSearchableContainerIface *iface);
28 G_DEFINE_TYPE_WITH_CODE (RygelMediaExportQueryContainer,
29 rygel_media_export_query_container,
30 RYGEL_MEDIA_EXPORT_TYPE_DB_CONTAINER,
31 G_IMPLEMENT_INTERFACE (RYGEL_TYPE_SEARCHABLE_CONTAINER,
32 rygel_media_export_query_container_rygel_searchable_container_interface_init))
34 struct _RygelMediaExportQueryContainerPrivate {
35 RygelSearchExpression *expression;
38 typedef struct _RygelMediaExportQueryContainerSearchData RygelMediaExportQueryContainerSearchData;
40 struct _RygelMediaExportQueryContainerSearchData {
42 RygelMediaObjects *result;
45 #define RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_GET_PRIVATE(o) \
46 (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
47 RYGEL_MEDIA_EXPORT_TYPE_QUERY_CONTAINER, \
48 RygelMediaExportQueryContainerPrivate))
51 RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_DUMMY_PROPERTY,
52 RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_EXPRESSION
56 rygel_media_export_query_container_real_search_data_free (gpointer user_data) {
57 RygelMediaExportQueryContainerSearchData *data = (RygelMediaExportQueryContainerSearchData *) user_data;
60 g_object_unref (data->result);
66 rygel_media_export_query_container_real_search (RygelSearchableContainer *base,
67 RygelSearchExpression *expression,
70 const gchar *sort_criteria,
71 GCancellable *cancellable G_GNUC_UNUSED,
72 GAsyncReadyCallback callback,
74 RygelMediaExportQueryContainer *self = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER (base);
75 GSimpleAsyncResult *simple;
77 RygelMediaObjects *objects;
78 RygelSearchExpression *combined;
80 RygelMediaExportMediaCache *cache = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
83 combined = rygel_search_expression_ref (self->priv->expression);
85 combined = RYGEL_SEARCH_EXPRESSION (rygel_logical_expression_new ());
86 combined->operand1 = rygel_search_expression_ref (self->priv->expression);
87 combined->op = RYGEL_LOGICAL_OPERATOR_AND;
88 combined->operand2 = rygel_search_expression_ref (expression);
91 objects = rygel_media_export_media_cache_get_objects_by_search_expression (cache,
101 if (g_error_matches (error,
102 RYGEL_MEDIA_EXPORT_MEDIA_CACHE_ERROR,
103 RYGEL_MEDIA_EXPORT_MEDIA_CACHE_ERROR_UNSUPPORTED_SEARCH)) {
104 objects = rygel_media_objects_new ();
106 g_error_free (error);
112 simple = g_simple_async_result_new_take_error (G_OBJECT (self),
117 RygelMediaExportQueryContainerSearchData *data = g_slice_new0 (RygelMediaExportQueryContainerSearchData);
119 simple = g_simple_async_result_new (G_OBJECT (self),
122 rygel_media_export_query_container_real_search);
123 data->result = objects;
124 data->total_matches = matches;
125 g_simple_async_result_set_op_res_gpointer (simple,
127 rygel_media_export_query_container_real_search_data_free);
129 g_simple_async_result_complete_in_idle (simple);
130 g_object_unref (simple);
131 rygel_search_expression_unref (combined);
135 static RygelMediaObjects *
136 rygel_media_export_query_container_real_search_finish (RygelSearchableContainer *base G_GNUC_UNUSED,
138 guint *total_matches,
140 RygelMediaObjects* result;
141 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
142 RygelMediaExportQueryContainerSearchData* data;
144 if (g_simple_async_result_propagate_error (simple, error)) {
147 data = g_simple_async_result_get_op_res_gpointer (simple);
149 *total_matches = data->total_matches;
151 result = data->result;
157 static void rygel_media_export_query_container_dispose (GObject *object) {
158 RygelMediaExportQueryContainer *self = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER (object);
159 RygelMediaExportQueryContainerPrivate *priv = self->priv;
161 if (priv->expression) {
162 RygelSearchExpression *expression = priv->expression;
164 priv->expression = NULL;
165 rygel_search_expression_unref (expression);
167 G_OBJECT_CLASS (rygel_media_export_query_container_parent_class)->dispose (object);
171 rygel_media_export_query_container_get_property (GObject *object,
175 RygelMediaExportQueryContainer *self = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER (object);
176 RygelMediaExportQueryContainerPrivate *priv = self->priv;
178 switch (property_id) {
179 case RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_EXPRESSION:
180 rygel_value_set_search_expression (value, priv->expression);
184 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
190 rygel_media_export_query_container_set_property (GObject *object,
194 RygelMediaExportQueryContainer *self = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER (object);
195 RygelMediaExportQueryContainerPrivate *priv = self->priv;
197 switch (property_id) {
198 case RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_EXPRESSION:
199 /* construct only property */
200 priv->expression = rygel_value_get_search_expression (value);
201 rygel_search_expression_ref (priv->expression);
205 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
211 rygel_media_export_query_container_class_init (RygelMediaExportQueryContainerClass *query_container_class) {
212 GObjectClass *object_class = G_OBJECT_CLASS (query_container_class);
214 object_class->dispose = rygel_media_export_query_container_dispose;
215 object_class->set_property = rygel_media_export_query_container_set_property;
216 object_class->get_property = rygel_media_export_query_container_get_property;
218 g_object_class_install_property (object_class,
219 RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_EXPRESSION,
220 rygel_param_spec_search_expression ("expression",
223 RYGEL_TYPE_SEARCH_EXPRESSION,
224 G_PARAM_STATIC_NAME |
225 G_PARAM_STATIC_NICK |
226 G_PARAM_STATIC_BLURB |
229 G_PARAM_CONSTRUCT_ONLY));
231 g_type_class_add_private (query_container_class,
232 sizeof (RygelMediaExportQueryContainerPrivate));
236 static void rygel_media_export_query_container_init (RygelMediaExportQueryContainer *self) {
237 self->priv = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_GET_PRIVATE (self);
241 rygel_media_export_query_container_rygel_searchable_container_interface_init (RygelSearchableContainerIface *iface) {
242 iface->search = rygel_media_export_query_container_real_search;
243 iface->search_finish = rygel_media_export_query_container_real_search_finish;
244 /* iface should be a copy of parent_searchable_container_iface, so
245 * we don't have to override the {get,set}_search_classes funcs.
247 * iface->get_search_classes = parent_searchable_container_iface->get_search_classes;
248 * iface->set_search_classes = parent_searchable_container_iface->set_search_classes;
252 RygelSearchExpression *
253 rygel_media_export_query_container_get_expression (RygelMediaExportQueryContainer *self)
255 g_return_val_if_fail (RYGEL_MEDIA_EXPORT_IS_QUERY_CONTAINER (self), NULL);
257 return self->priv->expression;