Add initial source files for rygel-gst-0-10-plugins (1f5e770)
[profile/ivi/rygel-gst-0-10-plugins.git] / src / media-export / rygel-media-export-query-container.c
1 /*
2  * Copyright (C) 2009, 2010 Jens Georg <mail@jensge.org>.
3  * Copyright (C) 2012, 2013 Intel Corporation.
4  *
5  * This file is part of Rygel.
6  *
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.
11  *
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.
16  *
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.
20  */
21
22 #include "rygel-media-export-errors.h"
23 #include "rygel-media-export-query-container.h"
24
25 static void
26 rygel_media_export_query_container_rygel_searchable_container_interface_init (RygelSearchableContainerIface *iface);
27
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))
33
34 struct _RygelMediaExportQueryContainerPrivate {
35   RygelSearchExpression *expression;
36 };
37
38 typedef struct _RygelMediaExportQueryContainerSearchData RygelMediaExportQueryContainerSearchData;
39
40 struct _RygelMediaExportQueryContainerSearchData {
41   guint total_matches;
42   RygelMediaObjects *result;
43 };
44
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))
49
50 enum  {
51   RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_DUMMY_PROPERTY,
52   RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_EXPRESSION
53 };
54
55 static void
56 rygel_media_export_query_container_real_search_data_free (gpointer user_data) {
57   RygelMediaExportQueryContainerSearchData *data = (RygelMediaExportQueryContainerSearchData *) user_data;
58
59   if (data->result) {
60     g_object_unref (data->result);
61   }
62 }
63
64
65 static void
66 rygel_media_export_query_container_real_search (RygelSearchableContainer *base,
67                                                 RygelSearchExpression    *expression,
68                                                 guint                     offset,
69                                                 guint                     max_count,
70                                                 const gchar              *sort_criteria,
71                                                 GCancellable             *cancellable G_GNUC_UNUSED,
72                                                 GAsyncReadyCallback       callback,
73                                                 gpointer                  user_data) {
74   RygelMediaExportQueryContainer *self = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER (base);
75   GSimpleAsyncResult *simple;
76   guint matches = 0;
77   RygelMediaObjects *objects;
78   RygelSearchExpression *combined;
79   GError *error = NULL;
80   RygelMediaExportMediaCache *cache = rygel_media_export_db_container_get_media_db (RYGEL_MEDIA_EXPORT_DB_CONTAINER (self));
81
82   if (!expression) {
83     combined = rygel_search_expression_ref (self->priv->expression);
84   } else {
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);
89   }
90
91   objects = rygel_media_export_media_cache_get_objects_by_search_expression (cache,
92                                                                              combined,
93                                                                              NULL,
94                                                                              sort_criteria,
95                                                                              offset,
96                                                                              max_count,
97                                                                              &matches,
98                                                                              &error);
99
100   if (error) {
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 ();
105       matches = 0;
106       g_error_free (error);
107       error = NULL;
108     }
109   }
110
111   if (error) {
112     simple = g_simple_async_result_new_take_error (G_OBJECT (self),
113                                                    callback,
114                                                    user_data,
115                                                    error);
116   } else {
117     RygelMediaExportQueryContainerSearchData *data = g_slice_new0 (RygelMediaExportQueryContainerSearchData);
118
119     simple = g_simple_async_result_new (G_OBJECT (self),
120                                         callback,
121                                         user_data,
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,
126                                                data,
127                                                rygel_media_export_query_container_real_search_data_free);
128   }
129   g_simple_async_result_complete_in_idle (simple);
130   g_object_unref (simple);
131   rygel_search_expression_unref (combined);
132 }
133
134
135 static RygelMediaObjects *
136 rygel_media_export_query_container_real_search_finish (RygelSearchableContainer  *base G_GNUC_UNUSED,
137                                                        GAsyncResult              *res,
138                                                        guint                     *total_matches,
139                                                        GError                   **error) {
140   RygelMediaObjects* result;
141   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
142   RygelMediaExportQueryContainerSearchData* data;
143
144   if (g_simple_async_result_propagate_error (simple, error)) {
145     return NULL;
146   }
147   data = g_simple_async_result_get_op_res_gpointer (simple);
148   if (total_matches) {
149     *total_matches = data->total_matches;
150   }
151   result = data->result;
152   data->result = NULL;
153
154   return result;
155 }
156
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;
160
161   if (priv->expression) {
162     RygelSearchExpression *expression = priv->expression;
163
164     priv->expression = NULL;
165     rygel_search_expression_unref (expression);
166   }
167   G_OBJECT_CLASS (rygel_media_export_query_container_parent_class)->dispose (object);
168 }
169
170 static void
171 rygel_media_export_query_container_get_property (GObject    *object,
172                                                  guint       property_id,
173                                                  GValue     *value,
174                                                  GParamSpec *pspec) {
175   RygelMediaExportQueryContainer *self = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER (object);
176   RygelMediaExportQueryContainerPrivate *priv = self->priv;
177
178   switch (property_id) {
179   case RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_EXPRESSION:
180     rygel_value_set_search_expression (value, priv->expression);
181     break;
182
183   default:
184     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
185     break;
186   }
187 }
188
189 static void
190 rygel_media_export_query_container_set_property (GObject      *object,
191                                                  guint         property_id,
192                                                  const GValue *value,
193                                                  GParamSpec   *pspec) {
194   RygelMediaExportQueryContainer *self = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER (object);
195   RygelMediaExportQueryContainerPrivate *priv = self->priv;
196
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);
202     break;
203
204   default:
205     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
206     break;
207   }
208 }
209
210 static void
211 rygel_media_export_query_container_class_init (RygelMediaExportQueryContainerClass *query_container_class) {
212   GObjectClass *object_class = G_OBJECT_CLASS (query_container_class);
213
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;
217
218   g_object_class_install_property (object_class,
219                                    RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_EXPRESSION,
220                                    rygel_param_spec_search_expression ("expression",
221                                                                        "expression",
222                                                                        "expression",
223                                                                        RYGEL_TYPE_SEARCH_EXPRESSION,
224                                                                        G_PARAM_STATIC_NAME |
225                                                                        G_PARAM_STATIC_NICK |
226                                                                        G_PARAM_STATIC_BLURB |
227                                                                        G_PARAM_READABLE |
228                                                                        G_PARAM_WRITABLE |
229                                                                        G_PARAM_CONSTRUCT_ONLY));
230
231   g_type_class_add_private (query_container_class,
232                             sizeof (RygelMediaExportQueryContainerPrivate));
233 }
234
235
236 static void rygel_media_export_query_container_init (RygelMediaExportQueryContainer *self) {
237   self->priv = RYGEL_MEDIA_EXPORT_QUERY_CONTAINER_GET_PRIVATE (self);
238 }
239
240 static void
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.
246    *
247    * iface->get_search_classes = parent_searchable_container_iface->get_search_classes;
248    * iface->set_search_classes = parent_searchable_container_iface->set_search_classes;
249    */
250 }
251
252 RygelSearchExpression *
253 rygel_media_export_query_container_get_expression (RygelMediaExportQueryContainer *self)
254 {
255   g_return_val_if_fail (RYGEL_MEDIA_EXPORT_IS_QUERY_CONTAINER (self), NULL);
256
257   return self->priv->expression;
258 }