1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
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>
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))
38 PROP_SDB_SYM_TYPE_CONVERSION_HASH
,
42 struct _SymbolDBQueryResultPriv
45 GdaDataModel
*data_model
;
46 GdaDataModelIter
*iter
;
47 const GHashTable
*sym_type_conversion_hash
;
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
,
58 G_IMPLEMENT_INTERFACE (IANJUTA_TYPE_ITERABLE
,
59 isymbol_iter_iface_init
));
61 symbol_db_query_result_error_quark (void)
63 return g_quark_from_static_string ("symbol-db-query-return-error-quark");
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.
79 sdb_query_result_validate_field (SymbolDBQueryResult
*result
,
80 IAnjutaSymbolField field
,
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
);
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
);
110 sdb_query_result_init (SymbolDBQueryResult
*result
)
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
;
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
);
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
);
149 sdb_query_result_set_property (GObject
*object
, guint prop_id
,
150 const GValue
*value
, GParamSpec
*pspec
)
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
;
162 case PROP_SDB_COLUMNS
:
163 for (i
= 0; i
< IANJUTA_SYMBOL_FIELD_END
; i
++)
164 priv
->col_map
[i
] = -1;
166 cols_order
= g_value_get_pointer (value
);
167 while (!(*cols_order
== IANJUTA_SYMBOL_FIELD_END
))
169 priv
->col_map
[*cols_order
] = i
;
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
;
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
;
185 case PROP_SDB_SYM_TYPE_CONVERSION_HASH
:
186 priv
->sym_type_conversion_hash
= g_value_get_pointer (value
);
188 case PROP_SDB_PROJECT_ROOT
:
189 g_free (priv
->project_root
);
190 priv
->project_root
= g_value_dup_string (value
);
193 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
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
;
209 case PROP_SDB_DATA_ITER
:
210 g_value_set_object (value
, priv
->iter
);
212 case PROP_SDB_SYM_TYPE_CONVERSION_HASH
:
213 g_value_set_pointer (value
, (gpointer
) priv
->sym_type_conversion_hash
);
215 case PROP_SDB_PROJECT_ROOT
:
216 g_value_set_string (value
, priv
->project_root
);
219 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
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",
239 "List of data fields in the order found in data model terminated by end field",
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",
246 "GdaDataModel of the result set",
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
,
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
|
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",
270 G_PARAM_READABLE
| G_PARAM_WRITABLE
|
274 /* IAnjutaSymbol implementation */
276 isymbol_get_boolean (IAnjutaSymbol
*isymbol
, IAnjutaSymbolField field
,
279 SymbolDBQueryResult
*result
;
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
;
294 isymbol_get_int (IAnjutaSymbol
*isymbol
, IAnjutaSymbolField field
,
297 SymbolDBQueryResult
*result
;
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
);
309 if (field
== IANJUTA_SYMBOL_FIELD_TYPE
)
311 if (!G_VALUE_HOLDS_STRING (val
))
312 return (gint
) IANJUTA_SYMBOL_TYPE_NONE
;
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
);
322 isymbol_get_string (IAnjutaSymbol
*isymbol
, IAnjutaSymbolField field
,
325 SymbolDBQueryResult
*result
;
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
);
348 isymbol_get_file (IAnjutaSymbol
*isymbol
, GError
**err
)
350 SymbolDBQueryResult
*result
;
351 const gchar
* file_path
;
352 gchar
*abs_file_path
;
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
);
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
);
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
));
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 */
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);
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
);
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
);
420 isymbol_iter_last (IAnjutaIterable
*iterable
, GError
**err
)
422 GdaDataModel
*data_model
;
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
);
433 return gda_data_model_iter_move_to_row (result
->priv
->iter
, len
- 1);
437 isymbol_iter_foreach (IAnjutaIterable
*iterable
, GFunc callback
,
438 gpointer user_data
, GError
**err
)
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))
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
);
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
);
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
);
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");
495 isymbol_iter_assign (IAnjutaIterable
*iter
, IAnjutaIterable
*src_iter
, GError
**e
)
497 DEBUG_PRINT ("%s", "isymbol_iter_assign () UNIMPLEMENTED");
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
;
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
,
530 symbol_db_query_result_is_empty (SymbolDBQueryResult
*result
)
532 return result
->priv
->result_is_empty
;