1 /*
2 * Copyright (C) 2009 - 2010 Murray Cumming <murrayc@murrayc.com>
3 * Copyright (C) 2009 - 2012 Vivien Malerba <malerba@gnome-db.org>
4 * Copyright (C) 2010 David King <davidk@openismus.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 #include <string.h>
22 #include <glib/gi18n-lib.h>
23 #include "tools-favorites.h"
24 #include "tool-utils.h"
25 #include <libgda/thread-wrapper/gda-thread-wrapper.h>
26 #include <libgda/gda-sql-builder.h>
27 #include <sql-parser/gda-sql-parser.h>
28
29 struct _ToolsFavoritesPrivate {
30 GdaMetaStore *store;
31 GdaConnection *store_cnc;
32 };
33
34
35 /*
36 * Main static functions
37 */
38 static void gda_tools_favorites_class_init (ToolsFavoritesClass *klass);
39 static void gda_tools_favorites_init (ToolsFavorites *bfav);
40 static void gda_tools_favorites_dispose (GObject *object);
41
42 /* get a pointer to the parents to be able to call their destructor */
43 static GObjectClass *parent_class = NULL;
44
45 /* signals */
46 enum {
47 FAV_CHANGED,
48 LAST_SIGNAL
49 };
50
51 gint gda_tools_favorites_signals [LAST_SIGNAL] = { 0 };
52
53 GType
gda_tools_favorites_get_type(void)54 gda_tools_favorites_get_type (void)
55 {
56 static GType type = 0;
57
58 if (G_UNLIKELY (type == 0)) {
59 static GMutex registering;
60 static const GTypeInfo info = {
61 sizeof (ToolsFavoritesClass),
62 (GBaseInitFunc) NULL,
63 (GBaseFinalizeFunc) NULL,
64 (GClassInitFunc) gda_tools_favorites_class_init,
65 NULL,
66 NULL,
67 sizeof (ToolsFavorites),
68 0,
69 (GInstanceInitFunc) gda_tools_favorites_init,
70 0
71 };
72
73
74 g_mutex_lock (®istering);
75 if (type == 0)
76 type = g_type_register_static (G_TYPE_OBJECT, "ToolsFavorites", &info, 0);
77 g_mutex_unlock (®istering);
78 }
79 return type;
80 }
81
82 static void
gda_tools_favorites_class_init(ToolsFavoritesClass * klass)83 gda_tools_favorites_class_init (ToolsFavoritesClass *klass)
84 {
85 GObjectClass *object_class = G_OBJECT_CLASS (klass);
86 parent_class = g_type_class_peek_parent (klass);
87
88 gda_tools_favorites_signals [FAV_CHANGED] =
89 g_signal_new ("favorites-changed",
90 G_TYPE_FROM_CLASS (object_class),
91 G_SIGNAL_RUN_FIRST | G_SIGNAL_DETAILED,
92 G_STRUCT_OFFSET (ToolsFavoritesClass, favorites_changed),
93 NULL, NULL,
94 g_cclosure_marshal_VOID__VOID, G_TYPE_NONE,
95 0);
96
97 klass->favorites_changed = NULL;
98
99 object_class->dispose = gda_tools_favorites_dispose;
100 }
101
102 static void
gda_tools_favorites_init(ToolsFavorites * bfav)103 gda_tools_favorites_init (ToolsFavorites *bfav)
104 {
105 bfav->priv = g_new0 (ToolsFavoritesPrivate, 1);
106 bfav->priv->store = NULL;
107 bfav->priv->store_cnc = NULL;
108 }
109
110 static void
gda_tools_favorites_dispose(GObject * object)111 gda_tools_favorites_dispose (GObject *object)
112 {
113 ToolsFavorites *bfav;
114
115 g_return_if_fail (object != NULL);
116 g_return_if_fail (GDA_TOOLS_IS_FAVORITES (object));
117
118 bfav = GDA_TOOLS_FAVORITES (object);
119 if (bfav->priv) {
120 if (bfav->priv->store)
121 g_object_unref (bfav->priv->store);
122 if (bfav->priv->store_cnc)
123 g_object_unref (bfav->priv->store_cnc);
124
125 g_free (bfav->priv);
126 bfav->priv = NULL;
127 }
128
129 /* parent class */
130 parent_class->dispose (object);
131 }
132
133 /**
134 * gda_tools_favorites_new
135 *
136 * Creates a new #ToolsFavorites object
137 *
138 * Returns: the new object
139 */
140 ToolsFavorites*
gda_tools_favorites_new(GdaMetaStore * store)141 gda_tools_favorites_new (GdaMetaStore *store)
142 {
143 ToolsFavorites *bfav;
144
145 g_return_val_if_fail (GDA_IS_META_STORE (store), NULL);
146
147 bfav = GDA_TOOLS_FAVORITES (g_object_new (GDA_TOOLS_TYPE_FAVORITES, NULL));
148 bfav->priv->store = g_object_ref (store);
149
150 return bfav;
151 }
152
153 #define FAVORITES_TABLE_NAME "gda_sql_favorites"
154 #define FAVORITES_TABLE_DESC \
155 "<table name=\"" FAVORITES_TABLE_NAME "\"> " \
156 " <column name=\"id\" type=\"gint\" pkey=\"TRUE\" autoinc=\"TRUE\"/>" \
157 " <column name=\"session\" type=\"gint\"/>" \
158 " <column name=\"type\"/>" \
159 " <column name=\"name\" nullok=\"TRUE\"/>" \
160 " <column name=\"contents\"/>" \
161 " <column name=\"descr\" nullok=\"TRUE\"/>" \
162 " <unique>" \
163 " <column name=\"session\"/>" \
164 " <column name=\"type\"/>" \
165 " <column name=\"contents\"/>" \
166 " </unique>" \
167 "</table>"
168 #define FAVORDER_TABLE_NAME "gda_sql_favorder"
169 #define FAVORDER_TABLE_DESC \
170 "<table name=\"" FAVORDER_TABLE_NAME "\"> " \
171 " <column name=\"order_key\" type=\"gint\" pkey=\"TRUE\"/>" \
172 " <column name=\"fav_id\" type=\"gint\" pkey=\"TRUE\"/>" \
173 " <column name=\"rank\" type=\"gint\"/>" \
174 "</table>"
175
176 static gboolean
meta_store_addons_init(ToolsFavorites * bfav,GError ** error)177 meta_store_addons_init (ToolsFavorites *bfav, GError **error)
178 {
179 GError *lerror = NULL;
180 if (bfav->priv->store_cnc)
181 return TRUE;
182
183 if (!gda_meta_store_schema_add_custom_object (bfav->priv->store, FAVORITES_TABLE_DESC, &lerror)) {
184 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR,
185 "%s", _("Can't initialize dictionary to store favorites"));
186 g_warning ("Can't initialize dictionary to store favorites :%s",
187 lerror && lerror->message ? lerror->message : "No detail");
188 if (lerror)
189 g_error_free (lerror);
190 return FALSE;
191 }
192 if (!gda_meta_store_schema_add_custom_object (bfav->priv->store, FAVORDER_TABLE_DESC, &lerror)) {
193 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR,
194 "%s", _("Can't initialize dictionary to store favorites"));
195 g_warning ("Can't initialize dictionary to store favorites :%s",
196 lerror && lerror->message ? lerror->message : "No detail");
197 if (lerror)
198 g_error_free (lerror);
199 return FALSE;
200 }
201
202 bfav->priv->store_cnc = g_object_ref (gda_meta_store_get_internal_connection (bfav->priv->store));
203 return TRUE;
204 }
205
206 /**
207 * gda_tools_favorites_type_to_string:
208 * @type: a #ToolsFavoritesType
209 *
210 * Returns: a string representing @type
211 */
212 const gchar *
gda_tools_favorites_type_to_string(ToolsFavoritesType type)213 gda_tools_favorites_type_to_string (ToolsFavoritesType type)
214 {
215 switch (type) {
216 case GDA_TOOLS_FAVORITES_TABLES:
217 return "TABLE";
218 case GDA_TOOLS_FAVORITES_DIAGRAMS:
219 return "DIAGRAM";
220 case GDA_TOOLS_FAVORITES_QUERIES:
221 return "QUERY";
222 case GDA_TOOLS_FAVORITES_DATA_MANAGERS:
223 return "DATAMAN";
224 case GDA_TOOLS_FAVORITES_ACTIONS:
225 return "ACTION";
226 case GDA_TOOLS_FAVORITES_LDAP_DN:
227 return "LDAP_DN";
228 case GDA_TOOLS_FAVORITES_LDAP_CLASS:
229 return "LDAP_CLASS";
230 default:
231 g_warning ("Unknown type of favorite");
232 }
233
234 return "";
235 }
236
237 static ToolsFavoritesType
favorite_string_to_type(const gchar * str)238 favorite_string_to_type (const gchar *str)
239 {
240 if (*str == 'T')
241 return GDA_TOOLS_FAVORITES_TABLES;
242 else if (*str == 'D') {
243 if (str[1] == 'I')
244 return GDA_TOOLS_FAVORITES_DIAGRAMS;
245 else
246 return GDA_TOOLS_FAVORITES_DATA_MANAGERS;
247 }
248 else if (*str == 'Q')
249 return GDA_TOOLS_FAVORITES_QUERIES;
250 else if (*str == 'A')
251 return GDA_TOOLS_FAVORITES_ACTIONS;
252 else if (*str == 'L') {
253 if (strlen (str) == 7)
254 return GDA_TOOLS_FAVORITES_LDAP_DN;
255 else
256 return GDA_TOOLS_FAVORITES_LDAP_CLASS;
257 }
258 else
259 g_warning ("Unknown type '%s' of favorite", str);
260 return 0;
261 }
262
263 static gint
find_favorite_position(ToolsFavorites * bfav,gint fav_id,gint order_key)264 find_favorite_position (ToolsFavorites *bfav, gint fav_id, gint order_key)
265 {
266 GdaSqlBuilder *b;
267 GdaStatement *stmt;
268 GdaSet *params = NULL;
269 GdaDataModel *model;
270 gint pos = -1;
271
272 g_return_val_if_fail (fav_id >= 0, -1);
273
274 b = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
275 gda_sql_builder_add_field_value_id (b,
276 gda_sql_builder_add_id (b, "rank"), 0);
277 gda_sql_builder_select_add_target (b, FAVORDER_TABLE_NAME, NULL);
278 gda_sql_builder_set_where (b,
279 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_AND,
280 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
281 gda_sql_builder_add_id (b, "fav_id"),
282 gda_sql_builder_add_param (b, "favid", G_TYPE_INT, FALSE), 0),
283 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
284 gda_sql_builder_add_id (b, "order_key"),
285 gda_sql_builder_add_param (b, "okey", G_TYPE_INT, FALSE), 0),
286 0));
287
288 stmt = gda_sql_builder_get_statement (b, NULL);
289 g_object_unref (G_OBJECT (b));
290 if (!stmt)
291 return -1;
292 params = gda_set_new_inline (2,
293 "favid", G_TYPE_INT, fav_id,
294 "okey", G_TYPE_INT, order_key);
295 model = gda_connection_statement_execute_select (bfav->priv->store_cnc, stmt, params, NULL);
296 g_object_unref (stmt);
297 g_object_unref (params);
298
299 if (!model)
300 return -1;
301
302 gint nrows;
303 nrows = gda_data_model_get_n_rows (model);
304 if (nrows == 1) {
305 const GValue *cvalue;
306 cvalue = gda_data_model_get_value_at (model, 0, 0, NULL);
307 if (cvalue)
308 pos = g_value_get_int (cvalue);
309 }
310
311 g_object_unref (G_OBJECT (model));
312 return pos;
313 }
314
315 static gint
find_favorite_by_name(ToolsFavorites * bfav,guint session_id,const gchar * name,ToolsFavoritesType type,ToolsFavoritesAttributes * out_existing_fav,GError ** error)316 find_favorite_by_name (ToolsFavorites *bfav, guint session_id, const gchar *name, ToolsFavoritesType type,
317 ToolsFavoritesAttributes *out_existing_fav, GError **error)
318 {
319 GdaSqlBuilder *b;
320 GdaStatement *stmt;
321 GdaSet *params = NULL;
322 GdaDataModel *model;
323 gint favid = -1;
324
325 if (out_existing_fav)
326 memset (out_existing_fav, 0, sizeof (ToolsFavoritesAttributes));
327 g_return_val_if_fail (name, -1);
328
329 b = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
330 gda_sql_builder_add_field_value_id (b,
331 gda_sql_builder_add_id (b, "id"), 0);
332 gda_sql_builder_add_field_value_id (b,
333 gda_sql_builder_add_id (b, "type"), 0);
334 gda_sql_builder_add_field_value_id (b,
335 gda_sql_builder_add_id (b, "name"), 0);
336 gda_sql_builder_add_field_value_id (b,
337 gda_sql_builder_add_id (b, "descr"), 0);
338 gda_sql_builder_add_field_value_id (b,
339 gda_sql_builder_add_id (b, "contents"), 0);
340 gda_sql_builder_select_add_target (b, FAVORITES_TABLE_NAME, NULL);
341 gda_sql_builder_set_where (b,
342 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_AND,
343 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
344 gda_sql_builder_add_id (b, "session"),
345 gda_sql_builder_add_param (b, "session", G_TYPE_INT, FALSE), 0),
346 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
347 gda_sql_builder_add_id (b, "name"),
348 gda_sql_builder_add_param (b, "name", G_TYPE_INT, FALSE), 0),
349 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
350 gda_sql_builder_add_id (b, "type"),
351 gda_sql_builder_add_param (b, "type", G_TYPE_STRING, FALSE), 0)));
352
353 stmt = gda_sql_builder_get_statement (b, error);
354 g_object_unref (G_OBJECT (b));
355 if (!stmt)
356 return -1;
357 params = gda_set_new_inline (3,
358 "session", G_TYPE_INT, session_id,
359 "type", G_TYPE_STRING, gda_tools_favorites_type_to_string (type),
360 "name", G_TYPE_STRING, name);
361 model = gda_connection_statement_execute_select (bfav->priv->store_cnc, stmt, params, error);
362 g_object_unref (stmt);
363 g_object_unref (params);
364
365 if (model && gda_data_model_get_n_rows (model) == 1) {
366 const GValue *cvalue;
367 cvalue = gda_data_model_get_value_at (model, 0, 0, NULL);
368 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_INT))
369 favid = g_value_get_int (cvalue);
370
371 if (out_existing_fav) {
372 out_existing_fav->id = favid;
373 cvalue = gda_data_model_get_value_at (model, 1, 0, error);
374 if (cvalue)
375 out_existing_fav->type = favorite_string_to_type (g_value_get_string (cvalue));
376 cvalue = gda_data_model_get_value_at (model, 2, 0, error);
377 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING))
378 out_existing_fav->name = g_value_dup_string (cvalue);
379 cvalue = gda_data_model_get_value_at (model, 3, 0, error);
380 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING))
381 out_existing_fav->descr = g_value_dup_string (cvalue);
382 cvalue = gda_data_model_get_value_at (model, 4, 0, error);
383 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING))
384 out_existing_fav->contents = g_value_dup_string (cvalue);
385 }
386 }
387 if (model)
388 g_object_unref (model);
389 return favid;
390 }
391
392 /*
393 * Find a favorite ID from its ID or from its contents
394 *
395 * Returns: the ID or -1 if not found (and sets ERROR).
396 *
397 * if @out_existing_fav is not %NULL, then its attributes are set, use gda_tools_favorites_reset_attributes()
398 * to free.
399 */
400 static gint
find_favorite(ToolsFavorites * bfav,guint session_id,gint id,const gchar * contents,ToolsFavoritesAttributes * out_existing_fav,GError ** error)401 find_favorite (ToolsFavorites *bfav, guint session_id, gint id, const gchar *contents,
402 ToolsFavoritesAttributes *out_existing_fav, GError **error)
403 {
404 GdaSqlBuilder *b;
405 GdaStatement *stmt;
406 GdaSet *params = NULL;
407 GdaDataModel *model;
408 gint favid = -1;
409
410 if (out_existing_fav)
411 memset (out_existing_fav, 0, sizeof (ToolsFavoritesAttributes));
412 g_return_val_if_fail ((id >= 0) || contents, -1);
413
414 b = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
415 gda_sql_builder_add_field_value_id (b,
416 gda_sql_builder_add_id (b, "id"), 0);
417 gda_sql_builder_add_field_value_id (b,
418 gda_sql_builder_add_id (b, "type"), 0);
419 gda_sql_builder_add_field_value_id (b,
420 gda_sql_builder_add_id (b, "name"), 0);
421 gda_sql_builder_add_field_value_id (b,
422 gda_sql_builder_add_id (b, "descr"), 0);
423 gda_sql_builder_add_field_value_id (b,
424 gda_sql_builder_add_id (b, "contents"), 0);
425 gda_sql_builder_select_add_target (b, FAVORITES_TABLE_NAME, NULL);
426
427 if (id >= 0) {
428 /* lookup from ID */
429 gda_sql_builder_set_where (b,
430 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
431 gda_sql_builder_add_id (b, "id"),
432 gda_sql_builder_add_param (b, "id", G_TYPE_INT, FALSE), 0));
433 }
434 else {
435 /* lookup using session and contents */
436 gda_sql_builder_set_where (b,
437 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_AND,
438 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
439 gda_sql_builder_add_id (b, "session"),
440 gda_sql_builder_add_param (b, "session", G_TYPE_INT, FALSE), 0),
441 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
442 gda_sql_builder_add_id (b, "contents"),
443 gda_sql_builder_add_param (b, "contents", G_TYPE_INT, FALSE), 0), 0));
444 }
445 stmt = gda_sql_builder_get_statement (b, error);
446 g_object_unref (G_OBJECT (b));
447 if (!stmt)
448 return -1;
449 params = gda_set_new_inline (3,
450 "session", G_TYPE_INT, session_id,
451 "id", G_TYPE_INT, id,
452 "contents", G_TYPE_STRING, contents);
453 model = gda_connection_statement_execute_select (bfav->priv->store_cnc, stmt, params, error);
454 g_object_unref (stmt);
455 g_object_unref (params);
456
457 if (!model)
458 return -1;
459
460 gint nrows;
461 nrows = gda_data_model_get_n_rows (model);
462 if (nrows == 1) {
463 const GValue *cvalue;
464 cvalue = gda_data_model_get_value_at (model, 0, 0, error);
465 if (cvalue)
466 favid = g_value_get_int (cvalue);
467 if (out_existing_fav) {
468 out_existing_fav->id = favid;
469 cvalue = gda_data_model_get_value_at (model, 1, 0, error);
470 if (cvalue)
471 out_existing_fav->type = favorite_string_to_type (g_value_get_string (cvalue));
472 cvalue = gda_data_model_get_value_at (model, 2, 0, error);
473 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING))
474 out_existing_fav->name = g_value_dup_string (cvalue);
475 cvalue = gda_data_model_get_value_at (model, 3, 0, error);
476 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING))
477 out_existing_fav->descr = g_value_dup_string (cvalue);
478 cvalue = gda_data_model_get_value_at (model, 4, 0, error);
479 if (cvalue && (G_VALUE_TYPE (cvalue) == G_TYPE_STRING))
480 out_existing_fav->contents = g_value_dup_string (cvalue);
481 }
482 }
483
484 g_object_unref (G_OBJECT (model));
485 return favid;
486 }
487
488 /*
489 * Reorders the favorites for @order_key, making sure @id is at position @new_pos
490 */
491 static gboolean
favorites_reorder(ToolsFavorites * bfav,gint order_key,gint id,gint new_pos,GError ** error)492 favorites_reorder (ToolsFavorites *bfav, gint order_key, gint id, gint new_pos, GError **error)
493 {
494 GdaSqlBuilder *b;
495 GdaStatement *stmt;
496 GdaSet *params = NULL;
497 GdaDataModel *model;
498
499 g_assert (id >= 0);
500 g_assert (order_key >= 0);
501
502 b = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
503 gda_sql_builder_add_field_value_id (b, gda_sql_builder_add_id (b, "fav_id"), 0);
504
505 gda_sql_builder_select_add_target (b, FAVORDER_TABLE_NAME, NULL);
506
507 gda_sql_builder_set_where (b, gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
508 gda_sql_builder_add_id (b, "order_key"),
509 gda_sql_builder_add_param (b, "orderkey", G_TYPE_INT, FALSE), 0));
510 gda_sql_builder_select_order_by (b,
511 gda_sql_builder_add_id (b, "rank"), TRUE, NULL);
512 stmt = gda_sql_builder_get_statement (b, error);
513 g_object_unref (G_OBJECT (b));
514 if (!stmt)
515 return FALSE;
516 params = gda_set_new_inline (3,
517 "orderkey", G_TYPE_INT, order_key,
518 "rank", G_TYPE_INT, 0,
519 "id", G_TYPE_INT, id);
520 model = gda_connection_statement_execute_select (bfav->priv->store_cnc, stmt, params, error);
521 g_object_unref (stmt);
522 if (!model) {
523 g_object_unref (params);
524 return FALSE;
525 }
526
527 gint i, nrows;
528 gboolean retval = TRUE;
529 nrows = gda_data_model_get_n_rows (model);
530 if (new_pos < 0)
531 new_pos = 0;
532 else if (new_pos > nrows)
533 new_pos = nrows;
534
535 b = gda_sql_builder_new (GDA_SQL_STATEMENT_UPDATE);
536 gda_sql_builder_set_table (b, FAVORDER_TABLE_NAME);
537 gda_sql_builder_add_field_value_id (b,
538 gda_sql_builder_add_id (b, "rank"),
539 gda_sql_builder_add_param (b, "rank", G_TYPE_INT, FALSE));
540 const GdaSqlBuilderId id_cond1 = gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
541 gda_sql_builder_add_id (b, "fav_id"),
542 gda_sql_builder_add_param (b, "id", G_TYPE_INT, FALSE),
543 0);
544 const GdaSqlBuilderId id_cond2 = gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
545 gda_sql_builder_add_id (b, "order_key"),
546 gda_sql_builder_add_param (b, "orderkey", G_TYPE_INT, FALSE),
547 0);
548 gda_sql_builder_set_where (b, gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_AND, id_cond1, id_cond2, 0));
549 stmt = gda_sql_builder_get_statement (b, error);
550 if (!stmt) {
551 retval = FALSE;
552 goto out;
553 }
554
555 /* reodering the rows */
556 for (i = 0; i < nrows; i++) {
557 const GValue *v;
558 v = gda_data_model_get_value_at (model, 0, i, error);
559 if (v) {
560 g_assert (gda_holder_set_value (gda_set_get_holder (params, "id"), v, NULL));
561 if (g_value_get_int (v) == id)
562 g_assert (gda_set_set_holder_value (params, NULL, "rank", new_pos));
563 else
564 g_assert (gda_set_set_holder_value (params, NULL, "rank", i < new_pos ? i : i + 1));
565 if (gda_connection_statement_execute_non_select (bfav->priv->store_cnc, stmt,
566 params, NULL, error) == -1) {
567 retval = FALSE;
568 goto out;
569 }
570 }
571 else {
572 retval = FALSE;
573 goto out;
574 }
575 }
576
577 out:
578 g_object_unref (b);
579 g_object_unref (params);
580 g_object_unref (model);
581 if (stmt)
582 g_object_unref (stmt);
583 return retval;
584 }
585
586 /**
587 * gda_tools_favorites_add
588 * @bfav: a #ToolsFavorites object
589 * @session_id: session ID (0)
590 * @fav: a pointer to a #ToolsFavoritesAttributes structure
591 * @order_key: ordering key or -1 for none
592 * @pos: position (ignored if @order_key < 0)
593 * @error: a place to store errors, or %NULL
594 *
595 * Add a new favorite, or replace an existing one.
596 * NOTE:
597 * <itemizedlist>
598 * <listitem><para>if @fav->id is < 0 then it's either an update or an insert (depending if fav->contents exists)
599 * and if it's not it is an INSERT </para></listitem>
600 * <listitem><para>@fav->type can't be 0</para></listitem>
601 * <listitem><para>@fav->contents can't be %NULL</para></listitem>
602 * </itemizedlist>
603 *
604 * On success @fav->id contains the favorite's ID, otherwise it will contain -1.
605 *
606 * if @order_key is negative, then no ordering is done and @pos is ignored.
607 */
608 gboolean
gda_tools_favorites_add(ToolsFavorites * bfav,guint session_id,ToolsFavoritesAttributes * fav,gint order_key,gint pos,GError ** error)609 gda_tools_favorites_add (ToolsFavorites *bfav, guint session_id,
610 ToolsFavoritesAttributes *fav,
611 gint order_key, gint pos,
612 GError **error)
613 {
614 GdaConnection *store_cnc;
615 GdaSet *params = NULL;
616 gint favid = -1;
617 ToolsFavoritesAttributes efav; /* existing favorite */
618
619 g_return_val_if_fail (GDA_TOOLS_IS_FAVORITES (bfav), FALSE);
620 g_return_val_if_fail (fav, FALSE);
621 g_return_val_if_fail (fav->contents, FALSE);
622
623 if (! meta_store_addons_init (bfav, error))
624 return FALSE;
625
626 store_cnc = bfav->priv->store_cnc;
627 if (! gda_lockable_trylock (GDA_LOCKABLE (store_cnc))) {
628 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR,
629 "%s", _("Can't initialize transaction to access favorites"));
630 return FALSE;
631 }
632 /* begin a transaction */
633 if (! gda_connection_begin_transaction (store_cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN, NULL)) {
634 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR,
635 "%s", _("Can't initialize transaction to access favorites"));
636 gda_lockable_unlock (GDA_LOCKABLE (store_cnc));
637 return FALSE;
638 }
639
640 gint rtype;
641 favid = find_favorite (bfav, session_id, fav->id, fav->contents, &efav, NULL);
642 rtype = fav->type;
643 if (efav.type)
644 rtype = efav.type;
645 if ((favid != -1) && (pos == G_MAXINT)) {
646 /* find current position */
647 pos = find_favorite_position (bfav, favid, order_key);
648 }
649 params = gda_set_new_inline (8,
650 "session", G_TYPE_INT, session_id,
651 "id", G_TYPE_INT, fav->id,
652 "type", G_TYPE_STRING, gda_tools_favorites_type_to_string (rtype),
653 "name", G_TYPE_STRING, fav->name ? fav->name : efav.name,
654 "contents", G_TYPE_STRING, fav->contents,
655 "rank", G_TYPE_INT, pos,
656 "orderkey", G_TYPE_INT, order_key,
657 "descr", G_TYPE_STRING, fav->descr ? fav->descr : efav.descr);
658
659 if (favid == -1) {
660 /* insert a favorite */
661 GdaSqlBuilder *builder;
662 GdaStatement *stmt;
663
664 g_return_val_if_fail (fav->type, FALSE);
665 builder = gda_sql_builder_new (GDA_SQL_STATEMENT_INSERT);
666 gda_sql_builder_set_table (builder, FAVORITES_TABLE_NAME);
667
668 gda_sql_builder_add_field_value_id (builder,
669 gda_sql_builder_add_id (builder, "session"),
670 gda_sql_builder_add_param (builder, "session", G_TYPE_INT, FALSE));
671 gda_sql_builder_add_field_value_id (builder,
672 gda_sql_builder_add_id (builder, "type"),
673 gda_sql_builder_add_param (builder, "type", G_TYPE_INT, FALSE));
674 gda_sql_builder_add_field_value_id (builder,
675 gda_sql_builder_add_id (builder, "name"),
676 gda_sql_builder_add_param (builder, "name", G_TYPE_STRING, TRUE));
677 gda_sql_builder_add_field_value_id (builder,
678 gda_sql_builder_add_id (builder, "contents"),
679 gda_sql_builder_add_param (builder, "contents", G_TYPE_STRING, FALSE));
680 gda_sql_builder_add_field_value_id (builder,
681 gda_sql_builder_add_id (builder, "descr"),
682 gda_sql_builder_add_param (builder, "descr", G_TYPE_STRING, TRUE));
683 stmt = gda_sql_builder_get_statement (builder, error);
684 g_object_unref (G_OBJECT (builder));
685 if (!stmt)
686 goto err;
687 if (gda_connection_statement_execute_non_select (store_cnc, stmt, params, NULL, error) == -1) {
688 g_object_unref (stmt);
689 goto err;
690 }
691 g_object_unref (stmt);
692
693 favid = find_favorite (bfav, session_id, fav->id, fav->contents, &efav, NULL);
694 fav->id = favid;
695 }
696 else {
697 /* update favorite's contents */
698 GdaSqlBuilder *builder;
699 GdaStatement *stmt;
700
701 gda_set_set_holder_value (params, NULL, "id", favid);
702 builder = gda_sql_builder_new (GDA_SQL_STATEMENT_UPDATE);
703 gda_sql_builder_set_table (builder, FAVORITES_TABLE_NAME);
704
705 gda_sql_builder_add_field_value_id (builder,
706 gda_sql_builder_add_id (builder, "name"),
707 gda_sql_builder_add_param (builder, "name", G_TYPE_STRING, TRUE));
708 gda_sql_builder_add_field_value_id (builder,
709 gda_sql_builder_add_id (builder, "contents"),
710 gda_sql_builder_add_param (builder, "contents", G_TYPE_STRING, FALSE));
711 gda_sql_builder_add_field_value_id (builder,
712 gda_sql_builder_add_id (builder, "descr"),
713 gda_sql_builder_add_param (builder, "descr", G_TYPE_STRING, TRUE));
714
715 gda_sql_builder_set_where (builder,
716 gda_sql_builder_add_cond (builder, GDA_SQL_OPERATOR_TYPE_EQ,
717 gda_sql_builder_add_id (builder, "id"),
718 gda_sql_builder_add_param (builder, "id", G_TYPE_INT, FALSE),
719 0));
720 if (fav->id == favid) {
721 /* alter name and description only if fav->id was OK */
722 gda_sql_builder_add_field_value_id (builder,
723 gda_sql_builder_add_id (builder, "name"),
724 gda_sql_builder_add_param (builder, "name", G_TYPE_STRING,
725 TRUE));
726 gda_sql_builder_add_field_value_id (builder,
727 gda_sql_builder_add_id (builder, "descr"),
728 gda_sql_builder_add_param (builder, "descr", G_TYPE_STRING,
729 TRUE));
730 }
731
732 stmt = gda_sql_builder_get_statement (builder, error);
733 g_object_unref (G_OBJECT (builder));
734 if (!stmt)
735 goto err;
736 if (gda_connection_statement_execute_non_select (store_cnc, stmt, params, NULL, error) == -1) {
737 g_object_unref (stmt);
738 goto err;
739 }
740 g_object_unref (stmt);
741 fav->id = favid;
742 }
743 gda_tools_favorites_reset_attributes (&efav);
744
745 if (order_key >= 0) {
746 GdaSqlBuilder *builder;
747 GdaStatement *stmt;
748
749 /* delete and insert favorite in orders table */
750 favid = find_favorite (bfav, session_id, fav->id, fav->contents, NULL, error);
751 if (favid < 0) {
752 g_warning ("Could not identify favorite by its ID, make sure it's correct");
753 goto err;
754 }
755
756 gda_set_set_holder_value (params, NULL, "id", favid);
757
758 builder = gda_sql_builder_new (GDA_SQL_STATEMENT_DELETE);
759 gda_sql_builder_set_table (builder, FAVORDER_TABLE_NAME);
760 gda_sql_builder_set_where (builder,
761 gda_sql_builder_add_cond (builder, GDA_SQL_OPERATOR_TYPE_AND,
762 gda_sql_builder_add_cond (builder, GDA_SQL_OPERATOR_TYPE_EQ,
763 gda_sql_builder_add_id (builder, "fav_id"),
764 gda_sql_builder_add_param (builder, "id", G_TYPE_INT, FALSE),
765 0),
766 gda_sql_builder_add_cond (builder, GDA_SQL_OPERATOR_TYPE_EQ,
767 gda_sql_builder_add_id (builder, "order_key"),
768 gda_sql_builder_add_param (builder, "orderkey", G_TYPE_INT, FALSE),
769 0), 0));
770 stmt = gda_sql_builder_get_statement (builder, error);
771 g_object_unref (G_OBJECT (builder));
772 if (!stmt)
773 goto err;
774 if (gda_connection_statement_execute_non_select (store_cnc, stmt, params, NULL, error) == -1) {
775 g_object_unref (stmt);
776 goto err;
777 }
778 g_object_unref (stmt);
779
780 builder = gda_sql_builder_new (GDA_SQL_STATEMENT_INSERT);
781 gda_sql_builder_set_table (builder, FAVORDER_TABLE_NAME);
782 gda_sql_builder_add_field_value_id (builder,
783 gda_sql_builder_add_id (builder, "fav_id"),
784 gda_sql_builder_add_param (builder, "id", G_TYPE_INT, FALSE));
785 gda_sql_builder_add_field_value_id (builder,
786 gda_sql_builder_add_id (builder, "rank"),
787 gda_sql_builder_add_param (builder, "rank", G_TYPE_INT, FALSE));
788 gda_sql_builder_add_field_value_id (builder,
789 gda_sql_builder_add_id (builder, "order_key"),
790 gda_sql_builder_add_param (builder, "orderkey", G_TYPE_STRING, TRUE));
791 stmt = gda_sql_builder_get_statement (builder, error);
792 g_object_unref (G_OBJECT (builder));
793 if (!stmt)
794 goto err;
795 if (gda_connection_statement_execute_non_select (store_cnc, stmt, params, NULL, error) == -1) {
796 g_object_unref (stmt);
797 goto err;
798 }
799 g_object_unref (stmt);
800
801 /* reorder */
802 if (!favorites_reorder (bfav, order_key, favid, pos, error))
803 goto err;
804 }
805
806 if (! gda_connection_commit_transaction (store_cnc, NULL, NULL)) {
807 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR,
808 "%s", _("Can't commit transaction to access favorites"));
809 goto err;
810 }
811
812 if (params)
813 g_object_unref (params);
814 gda_lockable_unlock (GDA_LOCKABLE (store_cnc));
815 g_signal_emit (bfav, gda_tools_favorites_signals [FAV_CHANGED],
816 g_quark_from_string (gda_tools_favorites_type_to_string (rtype)));
817 return TRUE;
818
819 err:
820 if (params)
821 g_object_unref (params);
822 gda_lockable_unlock (GDA_LOCKABLE (store_cnc));
823 gda_connection_rollback_transaction (store_cnc, NULL, NULL);
824 return FALSE;
825 }
826
827 /**
828 * gda_tools_favorites_free_list
829 * @fav_list: a list of #ToolsFavoritesAttributes
830 *
831 * Frees all the #ToolsFavoritesAttributes of the @fav_list list, and frees the list
832 * itself.
833 */
834 void
gda_tools_favorites_free_list(GSList * fav_list)835 gda_tools_favorites_free_list (GSList *fav_list)
836 {
837 GSList *list;
838 if (!fav_list)
839 return;
840 for (list = fav_list; list; list = list->next) {
841 ToolsFavoritesAttributes *fav = (ToolsFavoritesAttributes*) list->data;
842 gda_tools_favorites_reset_attributes (fav);
843 g_free (fav);
844 }
845 g_slist_free (fav_list);
846 }
847
848 /**
849 * gda_tools_favorites_reset_attributes
850 * @fav: a pointer to a #ToolsFavoritesAttributes
851 *
852 * Resets @fav with empty attributes; it does not free @fav.
853 */
854 void
gda_tools_favorites_reset_attributes(ToolsFavoritesAttributes * fav)855 gda_tools_favorites_reset_attributes (ToolsFavoritesAttributes *fav)
856 {
857 g_free (fav->name);
858 g_free (fav->descr);
859 g_free (fav->contents);
860 memset (fav, 0, sizeof (ToolsFavoritesAttributes));
861 }
862
863 /**
864 * gda_tools_favorites_list
865 * @bfav: a #ToolsFavorites
866 * @session_id: 0 for now
867 * @type: filter the type of attributes to be listed
868 * @order_key: a key to order the listed favorites, such as #ORDER_KEY_SCHEMA
869 * @error: a place to store errors, or %NULL
870 *
871 * Extract some favorites.
872 *
873 * Returns: a new list of #ToolsFavoritesAttributes pointers. The list has to
874 * be freed using gda_tools_favorites_free_list()
875 */
876 GSList *
gda_tools_favorites_list(ToolsFavorites * bfav,guint session_id,ToolsFavoritesType type,gint order_key,GError ** error)877 gda_tools_favorites_list (ToolsFavorites *bfav, guint session_id, ToolsFavoritesType type,
878 gint order_key, GError **error)
879 {
880 GdaSqlBuilder *b;
881 GdaSet *params = NULL;
882 GdaStatement *stmt;
883 GdaSqlBuilderId t1, t2;
884 GdaDataModel *model = NULL;
885 GSList *fav_list = NULL;
886
887 guint and_cond_ids [3];
888 int and_cond_size = 0;
889 guint or_cond_ids [GDA_TOOLS_FAVORITES_NB_TYPES];
890 int or_cond_size = 0;
891
892 g_return_val_if_fail (GDA_TOOLS_IS_FAVORITES (bfav), NULL);
893 g_return_val_if_fail ((type != 0) || (order_key >= 0), NULL);
894
895 if (! meta_store_addons_init (bfav, error))
896 return NULL;
897
898 b = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
899 gda_sql_builder_add_field_value_id (b,
900 gda_sql_builder_add_id (b, "fav.contents"), 0);
901 gda_sql_builder_add_field_value_id (b,
902 gda_sql_builder_add_id (b, "fav.descr"), 0);
903 gda_sql_builder_add_field_value_id (b,
904 gda_sql_builder_add_id (b, "fav.name"), 0);
905 gda_sql_builder_add_field_value_id (b,
906 gda_sql_builder_add_id (b, "fav.type"), 0);
907 gda_sql_builder_add_field_value_id (b,
908 gda_sql_builder_add_id (b, "fav.id"), 0);
909
910 t1 = gda_sql_builder_select_add_target (b, FAVORITES_TABLE_NAME, "fav");
911 if (order_key > 0) {
912 t2 = gda_sql_builder_select_add_target (b, FAVORDER_TABLE_NAME, "o");
913 gda_sql_builder_select_join_targets (b, t1, t2, GDA_SQL_SELECT_JOIN_LEFT,
914 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
915 gda_sql_builder_add_id (b, "fav.id"),
916 gda_sql_builder_add_id (b, "o.fav_id"),
917 0));
918 gda_sql_builder_select_order_by (b,
919 gda_sql_builder_add_id (b, "o.rank"), TRUE, NULL);
920
921 and_cond_ids [and_cond_size] = gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
922 gda_sql_builder_add_id (b, "o.order_key"),
923 gda_sql_builder_add_param (b, "okey", G_TYPE_INT, TRUE),
924 0);
925 and_cond_size++;
926 }
927
928 and_cond_ids [and_cond_size] = gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
929 gda_sql_builder_add_id (b, "fav.session"),
930 gda_sql_builder_add_param (b, "session", G_TYPE_INT, FALSE), 0);
931 and_cond_size++;
932
933 gint i;
934 gint flag;
935 for (i = 0, flag = 1; i < GDA_TOOLS_FAVORITES_NB_TYPES; i++, flag <<= 1) {
936 if (type & flag) {
937 gchar *str;
938 str = g_strdup_printf ("'%s'", gda_tools_favorites_type_to_string (flag));
939 or_cond_ids [or_cond_size] = gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
940 gda_sql_builder_add_id (b, "fav.type"),
941 gda_sql_builder_add_id (b, str),
942 0);
943 g_free (str);
944 or_cond_size++;
945 }
946 }
947 if (or_cond_size >= 1) {
948 and_cond_ids [and_cond_size] = gda_sql_builder_add_cond_v (b, GDA_SQL_OPERATOR_TYPE_OR,
949 or_cond_ids, or_cond_size);
950 and_cond_size++;
951 }
952
953 gda_sql_builder_set_where (b,
954 gda_sql_builder_add_cond_v (b, GDA_SQL_OPERATOR_TYPE_AND, and_cond_ids, and_cond_size));
955 #ifdef GDA_DEBUG_NO
956 {
957 GdaSqlStatement *sqlst;
958 sqlst = gda_sql_builder_get_sql_statement (b);
959
960 g_print ("=>%s\n", gda_sql_statement_serialize (sqlst));
961 }
962 #endif
963
964 stmt = gda_sql_builder_get_statement (b, error);
965 g_object_unref (G_OBJECT (b));
966 if (!stmt)
967 goto out;
968
969 #ifdef GDA_DEBUG_NO
970 {
971 g_print ("=>%s\n", gda_statement_to_sql (stmt, NULL, NULL));
972 }
973 #endif
974
975
976 params = gda_set_new_inline (2,
977 "session", G_TYPE_INT, session_id,
978 "okey", G_TYPE_INT, order_key);
979
980 model = gda_connection_statement_execute_select (bfav->priv->store_cnc, stmt, params, error);
981 g_object_unref (stmt);
982 if (!model) {
983 g_warning ("Malformed dictionary database, cannot get favorites list (this should happen only while in dev.).");
984 goto out;
985 }
986
987 gint nrows;
988 nrows = gda_data_model_get_n_rows (model);
989 for (i = 0; i < nrows; i++) {
990 const GValue *contents, *descr = NULL, *name = NULL, *type = NULL, *id = NULL;
991
992 contents = gda_data_model_get_value_at (model, 0, i, error);
993 if (contents)
994 descr = gda_data_model_get_value_at (model, 1, i, error);
995 if (descr)
996 name = gda_data_model_get_value_at (model, 2, i, error);
997 if (name)
998 type = gda_data_model_get_value_at (model, 3, i, error);
999 if (type)
1000 id = gda_data_model_get_value_at (model, 4, i, error);
1001 if (id) {
1002 ToolsFavoritesAttributes *fav;
1003 fav = g_new0 (ToolsFavoritesAttributes, 1);
1004 fav->id = g_value_get_int (id);
1005 fav->type = favorite_string_to_type (g_value_get_string (type));
1006 if (G_VALUE_TYPE (descr) == G_TYPE_STRING)
1007 fav->descr = g_value_dup_string (descr);
1008 if (G_VALUE_TYPE (name) == G_TYPE_STRING)
1009 fav->name = g_value_dup_string (name);
1010 fav->contents = g_value_dup_string (contents);
1011 fav_list = g_slist_prepend (fav_list, fav);
1012 }
1013 else {
1014 gda_tools_favorites_free_list (fav_list);
1015 fav_list = NULL;
1016 goto out;
1017 }
1018 }
1019
1020 out:
1021 if (params)
1022 g_object_unref (G_OBJECT (params));
1023 if (model)
1024 g_object_unref (G_OBJECT (model));
1025
1026 return g_slist_reverse (fav_list);
1027 }
1028
1029
1030 /**
1031 * gda_tools_favorites_delete
1032 * @bfav: a #ToolsFavorites
1033 * @session_id: 0 for now
1034 * @fav: a pointer to a #ToolsFavoritesAttributes definning which favorite to delete
1035 * @error: a place to store errors, or %NULL
1036 *
1037 * Delete a favorite
1038 *
1039 * Returns: %TRUE if no error occurred.
1040 */
1041 gboolean
gda_tools_favorites_delete(ToolsFavorites * bfav,guint session_id,ToolsFavoritesAttributes * fav,GError ** error)1042 gda_tools_favorites_delete (ToolsFavorites *bfav, guint session_id,
1043 ToolsFavoritesAttributes *fav, GError **error)
1044 {
1045 GdaSqlBuilder *b;
1046 GdaSet *params = NULL;
1047 GdaStatement *stmt;
1048 gboolean retval = FALSE;
1049 gint favid = -1;
1050 ToolsFavoritesAttributes efav;
1051
1052 g_return_val_if_fail (GDA_TOOLS_IS_FAVORITES (bfav), FALSE);
1053 g_return_val_if_fail (fav, FALSE);
1054 g_return_val_if_fail ((fav->id >= 0) || fav->contents || fav->name , FALSE);
1055
1056 memset (&efav, 0, sizeof (ToolsFavoritesAttributes));
1057 if (! meta_store_addons_init (bfav, error))
1058 return FALSE;
1059
1060 if (! gda_lockable_trylock (GDA_LOCKABLE (bfav->priv->store_cnc))) {
1061 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR,
1062 "%s", _("Can't initialize transaction to access favorites"));
1063 return FALSE;
1064 }
1065 /* begin a transaction */
1066 if (! gda_connection_begin_transaction (bfav->priv->store_cnc, NULL,
1067 GDA_TRANSACTION_ISOLATION_UNKNOWN, NULL)) {
1068 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR,
1069 "%s", _("Can't initialize transaction to access favorites"));
1070 gda_lockable_unlock (GDA_LOCKABLE (bfav->priv->store_cnc));
1071 return FALSE;
1072 }
1073
1074 GError *lerror = NULL;
1075 if ((fav->id >= 0) || fav->contents) {
1076 favid = find_favorite (bfav, session_id, fav->id, fav->contents, &efav, &lerror);
1077 if (lerror) {
1078 g_propagate_error (error, lerror);
1079 goto out;
1080 }
1081 }
1082 if ((favid < 0) && fav->name) {
1083 favid = find_favorite_by_name (bfav, session_id, fav->name, fav->type,
1084 &efav, &lerror);
1085 if (lerror) {
1086 g_propagate_error (error, lerror);
1087 goto out;
1088 }
1089 }
1090 if (favid < 0) {
1091 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_INTERNAL_COMMAND_ERROR,
1092 "%s", _("Could not find favorite"));
1093 goto out;
1094 }
1095
1096 /* remove entry from favorites' list */
1097 b = gda_sql_builder_new (GDA_SQL_STATEMENT_DELETE);
1098 gda_sql_builder_set_table (b, FAVORITES_TABLE_NAME);
1099 gda_sql_builder_set_where (b, gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
1100 gda_sql_builder_add_id (b, "id"),
1101 gda_sql_builder_add_param (b, "id", G_TYPE_INT, FALSE),
1102 0));
1103
1104 stmt = gda_sql_builder_get_statement (b, error);
1105 g_object_unref (G_OBJECT (b));
1106 if (!stmt)
1107 goto out;
1108
1109 params = gda_set_new_inline (1, "id", G_TYPE_INT, favid);
1110
1111 if (gda_connection_statement_execute_non_select (bfav->priv->store_cnc, stmt, params, NULL, error) == -1) {
1112 g_object_unref (stmt);
1113 goto out;
1114 }
1115 g_object_unref (stmt);
1116
1117 /* remove entry from favorites' order */
1118 b = gda_sql_builder_new (GDA_SQL_STATEMENT_DELETE);
1119 gda_sql_builder_set_table (b, FAVORDER_TABLE_NAME);
1120 gda_sql_builder_set_where (b, gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
1121 gda_sql_builder_add_id (b, "fav_id"),
1122 gda_sql_builder_add_param (b, "id", G_TYPE_INT, FALSE),
1123 0));
1124
1125 stmt = gda_sql_builder_get_statement (b, error);
1126 g_object_unref (G_OBJECT (b));
1127 if (!stmt)
1128 goto out;
1129 if (gda_connection_statement_execute_non_select (bfav->priv->store_cnc, stmt, params, NULL, error) == -1) {
1130 g_object_unref (stmt);
1131 goto out;
1132 }
1133 g_object_unref (stmt);
1134
1135 if (! gda_connection_commit_transaction (bfav->priv->store_cnc, NULL, NULL)) {
1136 g_set_error (error, GDA_TOOLS_ERROR, GDA_TOOLS_STORED_DATA_ERROR,
1137 "%s", _("Can't commit transaction to access favorites"));
1138 goto out;
1139 }
1140 retval = TRUE;
1141
1142 out:
1143 if (!retval)
1144 gda_connection_rollback_transaction (bfav->priv->store_cnc, NULL, NULL);
1145
1146 gda_lockable_unlock (GDA_LOCKABLE (bfav->priv->store_cnc));
1147 if (retval)
1148 g_signal_emit (bfav, gda_tools_favorites_signals [FAV_CHANGED],
1149 g_quark_from_string (gda_tools_favorites_type_to_string (efav.type)));
1150 gda_tools_favorites_reset_attributes (&efav);
1151 if (params)
1152 g_object_unref (G_OBJECT (params));
1153
1154 return retval;
1155 }
1156
1157 /**
1158 * gda_tools_favorites_find
1159 * @bfav: a #ToolsFavorites
1160 * @session_id: 0 for now
1161 * @contents: the favorite's contents
1162 * @out_fav: (allow-none): a #ToolsFavoritesAttributes to be filled with the favorite's attributes, or %NULL
1163 * @error: a place to store errors, or %NULL
1164 *
1165 * Get all the information about a favorite from its id: fills the @out_fav
1166 * pointed structure. Use gda_tools_favorites_reset_attributes() to reset @out_fav's contents.
1167 *
1168 * Retuns: the requested's favorite ID, or -1 if not found
1169 */
1170 gint
gda_tools_favorites_find(ToolsFavorites * bfav,guint session_id,const gchar * contents,ToolsFavoritesAttributes * out_fav,GError ** error)1171 gda_tools_favorites_find (ToolsFavorites *bfav, guint session_id, const gchar *contents,
1172 ToolsFavoritesAttributes *out_fav, GError **error)
1173 {
1174 g_return_val_if_fail (GDA_TOOLS_IS_FAVORITES (bfav), -1);
1175 g_return_val_if_fail (contents, -1);
1176
1177 if (! meta_store_addons_init (bfav, error))
1178 return -1;
1179 return find_favorite (bfav, session_id, -1, contents, out_fav, error);
1180 }
1181
1182 /**
1183 * gda_tools_favorites_find_by_name:
1184 * @bfav: a #ToolsFavorites
1185 * @session_id: 0 for now
1186 * @type: the favorite's type
1187 * @name: the favorite's name
1188 * @out_fav: (allow-none): a #ToolsFavoritesAttributes to be filled with the favorite's attributes, or %NULL
1189 * @error: a place to store errors, or %NULL
1190 *
1191 * Get all the information about a favorite from its id: fills the @out_fav
1192 * pointed structure. Use gda_tools_favorites_reset_attributes() to reset @out_fav's contents.
1193 *
1194 * Retuns: the requested's favorite ID, or -1 if not found
1195 */
1196 gint
gda_tools_favorites_find_by_name(ToolsFavorites * bfav,guint session_id,ToolsFavoritesType type,const gchar * name,ToolsFavoritesAttributes * out_fav,GError ** error)1197 gda_tools_favorites_find_by_name (ToolsFavorites *bfav, guint session_id, ToolsFavoritesType type, const gchar *name,
1198 ToolsFavoritesAttributes *out_fav, GError **error)
1199 {
1200 g_return_val_if_fail (GDA_TOOLS_IS_FAVORITES (bfav), -1);
1201 g_return_val_if_fail (name, -1);
1202
1203 if (! meta_store_addons_init (bfav, error))
1204 return -1;
1205 return find_favorite_by_name (bfav, session_id, name, type, out_fav, error);
1206 }
1207
1208
1209
1210 /**
1211 * gda_tools_favorites_get
1212 * @bfav: a #ToolsFavorites
1213 * @fav_id: the favorite's ID
1214 * @out_fav: a #ToolsFavoritesAttributes to be filled with the favorite's attributes
1215 * @error: a place to store errors, or %NULL
1216 *
1217 * Get all the information about a favorite from its id: fills the @out_fav
1218 * pointed structure. Use gda_tools_favorites_reset_attributes() to reset @out_fav's contents.
1219 *
1220 * Retuns: %TRUE if no error occurred.
1221 */
1222 gboolean
gda_tools_favorites_get(ToolsFavorites * bfav,gint fav_id,ToolsFavoritesAttributes * out_fav,GError ** error)1223 gda_tools_favorites_get (ToolsFavorites *bfav, gint fav_id,
1224 ToolsFavoritesAttributes *out_fav, GError **error)
1225 {
1226 GdaSqlBuilder *b;
1227 GdaStatement *stmt;
1228 GdaSet *params = NULL;
1229 GdaDataModel *model;
1230 gboolean retval = FALSE;
1231
1232 g_return_val_if_fail (GDA_TOOLS_IS_FAVORITES (bfav), FALSE);
1233 g_return_val_if_fail (out_fav, FALSE);
1234 g_return_val_if_fail (fav_id >= 0, FALSE);
1235
1236 memset (out_fav, 0, sizeof (ToolsFavoritesAttributes));
1237
1238 b = gda_sql_builder_new (GDA_SQL_STATEMENT_SELECT);
1239 gda_sql_builder_add_field_value_id (b,
1240 gda_sql_builder_add_id (b, "id"), 0);
1241 gda_sql_builder_add_field_value_id (b,
1242 gda_sql_builder_add_id (b, "type"), 0);
1243 gda_sql_builder_add_field_value_id (b,
1244 gda_sql_builder_add_id (b, "name"), 0);
1245 gda_sql_builder_add_field_value_id (b,
1246 gda_sql_builder_add_id (b, "descr"), 0);
1247 gda_sql_builder_add_field_value_id (b,
1248 gda_sql_builder_add_id (b, "contents"), 0);
1249 gda_sql_builder_select_add_target (b, FAVORITES_TABLE_NAME, NULL);
1250
1251 gda_sql_builder_set_where (b,
1252 gda_sql_builder_add_cond (b, GDA_SQL_OPERATOR_TYPE_EQ,
1253 gda_sql_builder_add_id (b, "id"),
1254 gda_sql_builder_add_param (b, "id", G_TYPE_INT, FALSE), 0));
1255 stmt = gda_sql_builder_get_statement (b, error);
1256 g_object_unref (G_OBJECT (b));
1257 if (!stmt)
1258 return FALSE;
1259 params = gda_set_new_inline (1,
1260 "id", G_TYPE_INT, fav_id);
1261 model = gda_connection_statement_execute_select (bfav->priv->store_cnc, stmt, params, error);
1262 g_object_unref (stmt);
1263 g_object_unref (params);
1264
1265 if (!model)
1266 return FALSE;
1267
1268 gint nrows;
1269 nrows = gda_data_model_get_n_rows (model);
1270 if (nrows == 1) {
1271 gint i;
1272 const GValue *cvalues[5];
1273 for (i = 0; i < 5; i++) {
1274 cvalues [i] = gda_data_model_get_value_at (model, i, 0, error);
1275 if (!cvalues [i])
1276 goto out;
1277 }
1278
1279 out_fav->id = g_value_get_int (cvalues [0]);
1280 out_fav->type = favorite_string_to_type (g_value_get_string (cvalues [1]));
1281 if (G_VALUE_TYPE (cvalues [2]) == G_TYPE_STRING)
1282 out_fav->name = g_value_dup_string (cvalues [2]);
1283 if (G_VALUE_TYPE (cvalues [3]) == G_TYPE_STRING)
1284 out_fav->descr = g_value_dup_string (cvalues [3]);
1285 out_fav->contents = g_value_dup_string (cvalues [4]);
1286 retval = TRUE;
1287 }
1288
1289 out:
1290 g_object_unref (G_OBJECT (model));
1291 return retval;
1292 }
1293