Updated Spanish translation
[anjuta.git] / plugins / symbol-db / symbol-db-query-result.c
blobf5ff9031c12c979568250558ab87bdbe05918ef6
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * symbol-db-query-result.c
4 * Copyright (C) Massimo Cora' 2007-2008 <maxcvs@email.it>
5 * Copyright (C) Naba Kumar 2010 <naba@gnome.org>
6 *
7 * anjuta is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * anjuta is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 * See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <libanjuta/interfaces/ianjuta-symbol.h>
22 #include <libanjuta/interfaces/ianjuta-iterable.h>
23 #include <libanjuta/anjuta-utils.h>
24 #include <libanjuta/anjuta-debug.h>
26 #include <libgda/libgda.h>
27 #include "symbol-db-query-result.h"
28 #include "symbol-db-engine-utils.h"
30 #define SYMBOL_DB_QUERY_RESULT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
31 SYMBOL_DB_TYPE_QUERY_RESULT, SymbolDBQueryResultPriv))
33 enum {
34 PROP_SDB_0,
35 PROP_SDB_COLUMNS,
36 PROP_SDB_DATA_MODEL,
37 PROP_SDB_DATA_ITER,
38 PROP_SDB_SYM_TYPE_CONVERSION_HASH,
39 PROP_SDB_PROJECT_ROOT
42 struct _SymbolDBQueryResultPriv
44 gint *col_map;
45 GdaDataModel *data_model;
46 GdaDataModelIter *iter;
47 const GHashTable *sym_type_conversion_hash;
48 gchar *project_root;
49 gboolean result_is_empty;
52 static void isymbol_iface_init (IAnjutaSymbolIface *iface);
53 static void isymbol_iter_iface_init (IAnjutaIterableIface *iface);
55 G_DEFINE_TYPE_WITH_CODE (SymbolDBQueryResult, sdb_query_result, G_TYPE_OBJECT,
56 G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_SYMBOL,
57 isymbol_iface_init)
58 G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_ITERABLE,
59 isymbol_iter_iface_init));
60 GQuark
61 symbol_db_query_result_error_quark (void)
63 return g_quark_from_static_string ("symbol-db-query-return-error-quark");
66 /**
67 * sdb_query_result_validate_field:
68 * @result: The resultset.
69 * @field: The requested field to validate.
70 * @err: The err to set (or NULL).
72 * Validates the query if the requested column is part of the resultset or
73 * within the valid range of columns. If not a warning is printed and the
74 * return error is set accordingly.
76 * Returns: TRUE if @field is valide, otherwise err is set if not NULL.
78 static gboolean
79 sdb_query_result_validate_field (SymbolDBQueryResult *result,
80 IAnjutaSymbolField field,
81 GError **err)
83 g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
85 if (field >= IANJUTA_SYMBOL_FIELD_END)
87 g_set_error (err, SYMBOL_DB_QUERY_RESULT_ERROR,
88 SYMBOL_DB_QUERY_RESULT_ERROR_INVALID_FIELD,
89 "Invalid symbol query field '%d'. It should be less than '%d'",
90 field, IANJUTA_SYMBOL_FIELD_END);
91 g_warning ("Invalid symbol query field '%d'. It should be less than '%d'",
92 field, IANJUTA_SYMBOL_FIELD_END);
93 return FALSE;
96 if (result->priv->col_map [field] == -1)
98 g_set_error (err, SYMBOL_DB_QUERY_RESULT_ERROR,
99 SYMBOL_DB_QUERY_RESULT_ERROR_FIELD_NOT_PRESENT,
100 "Symbol field '%d' is not present in the query. Make sure to "
101 "include it during query creation.", field);
102 g_warning ("Symbol field '%d' is not present in the query. Make sure to "
103 "include it during query creation.", field);
104 return FALSE;
106 return TRUE;
109 static void
110 sdb_query_result_init (SymbolDBQueryResult *result)
112 gint i;
114 result->priv = SYMBOL_DB_QUERY_RESULT_GET_PRIVATE (result);
115 result->priv->col_map = g_new (gint, IANJUTA_SYMBOL_FIELD_END);
116 for (i = 0; i < IANJUTA_SYMBOL_FIELD_END; i++)
117 result->priv->col_map[i] = -1;
118 result->priv->result_is_empty = TRUE;
121 static void
122 sdb_query_result_dispose (GObject *object)
124 SymbolDBQueryResult *result = SYMBOL_DB_QUERY_RESULT (object);
125 if (result->priv->data_model)
127 g_object_unref (result->priv->data_model);
128 result->priv->data_model = NULL;
130 if (result->priv->iter)
132 g_object_unref (result->priv->iter);
133 result->priv->iter = NULL;
135 G_OBJECT_CLASS (sdb_query_result_parent_class)->dispose (object);
138 static void
139 sdb_query_result_finalize (GObject *object)
141 SymbolDBQueryResult *result = SYMBOL_DB_QUERY_RESULT (object);
143 g_free (result->priv->project_root);
144 g_free (result->priv->col_map);
145 G_OBJECT_CLASS (sdb_query_result_parent_class)->finalize (object);
148 static void
149 sdb_query_result_set_property (GObject *object, guint prop_id,
150 const GValue *value, GParamSpec *pspec)
152 gint i;
153 GdaDataModel *data_model;
154 IAnjutaSymbolField *cols_order;
155 SymbolDBQueryResultPriv *priv;
157 g_return_if_fail (SYMBOL_DB_IS_QUERY_RESULT (object));
158 priv = SYMBOL_DB_QUERY_RESULT (object)->priv;
160 switch (prop_id)
162 case PROP_SDB_COLUMNS:
163 for (i = 0; i < IANJUTA_SYMBOL_FIELD_END; i++)
164 priv->col_map[i] = -1;
165 i = 0;
166 cols_order = g_value_get_pointer (value);
167 while (!(*cols_order == IANJUTA_SYMBOL_FIELD_END))
169 priv->col_map[*cols_order] = i;
170 i++;
171 cols_order++;
173 break;
174 case PROP_SDB_DATA_MODEL:
175 priv->result_is_empty = TRUE;
176 data_model = GDA_DATA_MODEL (g_value_get_object (value));
177 if (priv->data_model) g_object_unref (priv->data_model);
178 priv->data_model = data_model;
179 if (priv->iter)
180 g_object_unref (priv->iter);
181 priv->iter = gda_data_model_create_iter (data_model);
182 if (gda_data_model_iter_move_to_row (priv->iter, 0))
183 priv->result_is_empty = FALSE;
184 break;
185 case PROP_SDB_SYM_TYPE_CONVERSION_HASH:
186 priv->sym_type_conversion_hash = g_value_get_pointer (value);
187 break;
188 case PROP_SDB_PROJECT_ROOT:
189 g_free (priv->project_root);
190 priv->project_root = g_value_dup_string (value);
191 break;
192 default:
193 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
194 break;
198 static void
199 sdb_query_result_get_property (GObject *object, guint prop_id,
200 GValue *value, GParamSpec *pspec)
202 SymbolDBQueryResultPriv *priv;
204 g_return_if_fail (SYMBOL_DB_IS_QUERY_RESULT (object));
205 priv = SYMBOL_DB_QUERY_RESULT (object)->priv;
207 switch (prop_id)
209 case PROP_SDB_DATA_ITER:
210 g_value_set_object (value, priv->iter);
211 break;
212 case PROP_SDB_SYM_TYPE_CONVERSION_HASH:
213 g_value_set_pointer (value, (gpointer) priv->sym_type_conversion_hash);
214 break;
215 case PROP_SDB_PROJECT_ROOT:
216 g_value_set_string (value, priv->project_root);
217 break;
218 default:
219 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
220 break;
224 static void
225 sdb_query_result_class_init (SymbolDBQueryResultClass *klass)
227 GObjectClass* object_class = G_OBJECT_CLASS (klass);
229 g_type_class_add_private (klass, sizeof (SymbolDBQueryResultPriv));
230 object_class->set_property = sdb_query_result_set_property;
231 object_class->get_property = sdb_query_result_get_property;
232 object_class->finalize = sdb_query_result_finalize;
233 object_class->dispose = sdb_query_result_dispose;
235 g_object_class_install_property
236 (object_class, PROP_SDB_COLUMNS,
237 g_param_spec_pointer ("fields-order",
238 "Fields order",
239 "List of data fields in the order found in data model terminated by end field",
240 G_PARAM_WRITABLE |
241 G_PARAM_CONSTRUCT_ONLY));
242 g_object_class_install_property
243 (object_class, PROP_SDB_DATA_MODEL,
244 g_param_spec_object ("data-model",
245 "a GdaDataModel",
246 "GdaDataModel of the result set",
247 GDA_TYPE_DATA_MODEL,
248 G_PARAM_WRITABLE |
249 G_PARAM_CONSTRUCT_ONLY));
250 g_object_class_install_property
251 (object_class, PROP_SDB_DATA_ITER,
252 g_param_spec_object ("data-iter",
253 "a GdaDataModelIter",
254 "GdaDataModelIter on the result set",
255 GDA_TYPE_DATA_MODEL_ITER,
256 G_PARAM_READABLE));
257 g_object_class_install_property
258 (object_class, PROP_SDB_SYM_TYPE_CONVERSION_HASH,
259 g_param_spec_pointer ("sym-type-conversion-hash",
260 "Symbol type conversoin hash table",
261 "A hash table to convert string form of symbol type to enum value (fixme)",
262 G_PARAM_READABLE | G_PARAM_WRITABLE |
263 G_PARAM_CONSTRUCT));
264 g_object_class_install_property
265 (object_class, PROP_SDB_PROJECT_ROOT,
266 g_param_spec_string ("project-root",
267 "Project root directory",
268 "The project root directory",
269 NULL,
270 G_PARAM_READABLE | G_PARAM_WRITABLE |
271 G_PARAM_CONSTRUCT));
274 /* IAnjutaSymbol implementation */
275 static gboolean
276 isymbol_get_boolean (IAnjutaSymbol *isymbol, IAnjutaSymbolField field,
277 GError **err)
279 SymbolDBQueryResult *result;
280 const GValue *val;
281 gint col;
283 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (isymbol), FALSE);
285 result = SYMBOL_DB_QUERY_RESULT (isymbol);
286 if (!sdb_query_result_validate_field (result, field, err)) return FALSE;
288 col = result->priv->col_map[field];
289 val = gda_data_model_iter_get_value_at (result->priv->iter, col);
290 return g_value_get_int (val) == TRUE;
293 static gint
294 isymbol_get_int (IAnjutaSymbol *isymbol, IAnjutaSymbolField field,
295 GError **err)
297 SymbolDBQueryResult *result;
298 const GValue *val;
299 gint col;
301 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (isymbol), -1);
303 result = SYMBOL_DB_QUERY_RESULT (isymbol);
304 if (!sdb_query_result_validate_field (result, field, err)) return FALSE;
306 col = result->priv->col_map[field];
307 val = gda_data_model_iter_get_value_at (result->priv->iter, col);
308 if (!val) return 0;
309 if (field == IANJUTA_SYMBOL_FIELD_TYPE)
311 if (!G_VALUE_HOLDS_STRING (val))
312 return (gint) IANJUTA_SYMBOL_TYPE_NONE;
313 else
314 return GPOINTER_TO_INT (g_hash_table_lookup
315 ((GHashTable*)result->priv->sym_type_conversion_hash,
316 g_value_get_string (val)));
318 return g_value_get_int (val);
321 static const gchar*
322 isymbol_get_string (IAnjutaSymbol *isymbol, IAnjutaSymbolField field,
323 GError **err)
325 SymbolDBQueryResult *result;
326 const GValue *val;
327 gint col;
329 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (isymbol), NULL);
331 result = SYMBOL_DB_QUERY_RESULT (isymbol);
332 if (!sdb_query_result_validate_field (result, field, err)) return FALSE;
334 col = result->priv->col_map[field];
335 val = gda_data_model_iter_get_value_at (result->priv->iter, col);
336 if (!val) return NULL;
337 if (!G_VALUE_HOLDS_STRING (val)) return NULL;
338 return g_value_get_string (val);
341 static IAnjutaSymbolType
342 isymbol_get_sym_type (IAnjutaSymbol *isymbol, GError **err)
344 return (IAnjutaSymbolType)isymbol_get_int (isymbol, IANJUTA_SYMBOL_FIELD_TYPE, err);
347 static GFile*
348 isymbol_get_file (IAnjutaSymbol *isymbol, GError **err)
350 SymbolDBQueryResult *result;
351 const gchar* file_path;
352 gchar *abs_file_path;
353 GFile *file;
355 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (isymbol), NULL);
357 result = SYMBOL_DB_QUERY_RESULT (isymbol);
359 file_path = isymbol_get_string (isymbol, IANJUTA_SYMBOL_FIELD_FILE_PATH, err);
360 if (!file_path)
361 return NULL;
362 abs_file_path = g_build_filename (result->priv->project_root, file_path, NULL);
363 file = g_file_new_for_path (abs_file_path);
364 g_free (abs_file_path);
365 return file;
368 static const GdkPixbuf*
369 isymbol_get_icon (IAnjutaSymbol *isymbol, GError **err)
371 return symbol_db_util_get_pixbuf
372 (isymbol_get_string (isymbol, IANJUTA_SYMBOL_FIELD_TYPE, NULL),
373 isymbol_get_string (isymbol, IANJUTA_SYMBOL_FIELD_ACCESS, NULL));
376 static void
377 isymbol_iface_init (IAnjutaSymbolIface *iface)
379 iface->get_boolean = isymbol_get_boolean;
380 iface->get_int = isymbol_get_int;
381 iface->get_string = isymbol_get_string;
382 iface->get_sym_type = isymbol_get_sym_type;
383 iface->get_file = isymbol_get_file;
384 iface->get_icon = isymbol_get_icon;
387 /* IAnjutaIterable implementation */
389 static gboolean
390 isymbol_iter_first (IAnjutaIterable *iterable, GError **err)
392 SymbolDBQueryResult *result;
394 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (iterable), FALSE);
395 result = SYMBOL_DB_QUERY_RESULT (iterable);
396 return gda_data_model_iter_move_to_row (result->priv->iter, 0);
399 static gboolean
400 isymbol_iter_next (IAnjutaIterable *iterable, GError **err)
402 SymbolDBQueryResult *result;
404 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (iterable), FALSE);
405 result = SYMBOL_DB_QUERY_RESULT (iterable);
406 return gda_data_model_iter_move_next (result->priv->iter);
409 static gboolean
410 isymbol_iter_previous (IAnjutaIterable *iterable, GError **err)
412 SymbolDBQueryResult *result;
414 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (iterable), FALSE);
415 result = SYMBOL_DB_QUERY_RESULT (iterable);
416 return gda_data_model_iter_move_prev (result->priv->iter);
419 static gboolean
420 isymbol_iter_last (IAnjutaIterable *iterable, GError **err)
422 GdaDataModel *data_model;
423 gint len;
424 SymbolDBQueryResult *result;
426 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (iterable), FALSE);
427 result = SYMBOL_DB_QUERY_RESULT (iterable);
428 g_object_get (G_OBJECT (result->priv->iter), "data-model", &data_model, NULL);
429 len = gda_data_model_get_n_rows (data_model);
430 g_object_unref (data_model);
431 if (len <= 0)
432 return FALSE;
433 return gda_data_model_iter_move_to_row (result->priv->iter, len - 1);
436 static void
437 isymbol_iter_foreach (IAnjutaIterable *iterable, GFunc callback,
438 gpointer user_data, GError **err)
440 gint current;
441 SymbolDBQueryResult *result;
443 g_return_if_fail (SYMBOL_DB_IS_QUERY_RESULT (iterable));
444 result = SYMBOL_DB_QUERY_RESULT (iterable);
445 current = gda_data_model_iter_get_row (result->priv->iter);
446 if (!gda_data_model_iter_move_to_row (result->priv->iter, 0))
447 return;
450 callback (iterable, user_data);
452 while (gda_data_model_iter_move_next (result->priv->iter));
453 gda_data_model_iter_move_to_row (result->priv->iter, current);
456 static gboolean
457 isymbol_iter_set_position (IAnjutaIterable *iterable,
458 gint position, GError **err)
460 SymbolDBQueryResult *result;
462 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (iterable), FALSE);
463 result = SYMBOL_DB_QUERY_RESULT (iterable);
464 return gda_data_model_iter_move_to_row (result->priv->iter, position);
467 static gint
468 isymbol_iter_get_position (IAnjutaIterable *iterable, GError **err)
470 SymbolDBQueryResult *result;
472 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (iterable), FALSE);
473 result = SYMBOL_DB_QUERY_RESULT (iterable);
474 return gda_data_model_iter_get_row (result->priv->iter);
477 static gint
478 isymbol_iter_get_length (IAnjutaIterable *iterable, GError **err)
480 SymbolDBQueryResult *result;
482 g_return_val_if_fail (SYMBOL_DB_IS_QUERY_RESULT (iterable), FALSE);
483 result = SYMBOL_DB_QUERY_RESULT (iterable);
484 return gda_data_model_get_n_rows (result->priv->data_model);
487 static IAnjutaIterable *
488 isymbol_iter_clone (IAnjutaIterable *iter, GError **e)
490 DEBUG_PRINT ("%s", "isymbol_iter_clone () UNIMPLEMENTED");
491 return NULL;
494 static void
495 isymbol_iter_assign (IAnjutaIterable *iter, IAnjutaIterable *src_iter, GError **e)
497 DEBUG_PRINT ("%s", "isymbol_iter_assign () UNIMPLEMENTED");
500 static void
501 isymbol_iter_iface_init (IAnjutaIterableIface *iface)
503 iface->first = isymbol_iter_first;
504 iface->next = isymbol_iter_next;
505 iface->previous = isymbol_iter_previous;
506 iface->last = isymbol_iter_last;
507 iface->foreach = isymbol_iter_foreach;
508 iface->set_position = isymbol_iter_set_position;
509 iface->get_position = isymbol_iter_get_position;
510 iface->get_length = isymbol_iter_get_length;
511 iface->clone = isymbol_iter_clone;
512 iface->assign = isymbol_iter_assign;
515 SymbolDBQueryResult*
516 symbol_db_query_result_new (GdaDataModel *data_model,
517 IAnjutaSymbolField *fields_order,
518 const GHashTable *sym_type_conversion_hash,
519 const gchar *project_root_dir)
521 return g_object_new (SYMBOL_DB_TYPE_QUERY_RESULT,
522 "data-model", data_model,
523 "fields-order", fields_order,
524 "sym-type-conversion-hash", sym_type_conversion_hash,
525 "project-root", project_root_dir,
526 NULL);
529 gboolean
530 symbol_db_query_result_is_empty (SymbolDBQueryResult *result)
532 return result->priv->result_is_empty;