1 /*
2  * Copyright (C) 2012 Vivien Malerba <malerba@gnome-db.org>
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18 
19 #include <string.h>
20 #include <glib/gi18n-lib.h>
21 #include "favorites-actions.h"
22 #include "../browser-connection.h"
23 #include <libgda/gda-sql-builder.h>
24 #include <sql-parser/gda-sql-parser.h>
25 
26 static gint
actions_sort_func(ToolsFavoriteAction * act1,ToolsFavoriteAction * act2)27 actions_sort_func (ToolsFavoriteAction *act1, ToolsFavoriteAction *act2)
28 {
29 	return act2->nb_bound - act1->nb_bound;
30 }
31 
32 /**
33  * gda_tools_favorites_get_actions
34  * @bfav: a #ToolsFavorites
35  * @bcnc: a #BrowserConnection
36  * @set: a #GdaSet
37  *
38  * Get a list of #ToolsFavoriteAction which can be executed with the data in @set.
39  *
40  * Returns: a new list of #ToolsFavoriteAction, free list with gda_tools_favorites_free_actions()
41  */
42 GSList *
gda_tools_favorites_get_actions(ToolsFavorites * bfav,BrowserConnection * bcnc,GdaSet * set)43 gda_tools_favorites_get_actions (ToolsFavorites *bfav, BrowserConnection *bcnc, GdaSet *set)
44 {
45 	GSList *fav_list, *list, *retlist = NULL;
46 	g_return_val_if_fail (GDA_TOOLS_IS_FAVORITES (bfav), NULL);
47 	g_return_val_if_fail (BROWSER_IS_CONNECTION (bcnc), NULL);
48 	g_return_val_if_fail (!set || GDA_IS_SET (set), NULL);
49 
50 	fav_list = gda_tools_favorites_list (bfav, 0, GDA_TOOLS_FAVORITES_ACTIONS, -1, NULL);
51 	if (! fav_list)
52 		return NULL;
53 
54 	for (list = fav_list; list; list = list->next) {
55 		ToolsFavoritesAttributes *fa = (ToolsFavoritesAttributes*) list->data;
56 		ToolsFavoritesAttributes qfa;
57 		if (! g_str_has_prefix (fa->contents, "QUERY")) {
58 			g_warning ("Malformed action contents '%s', please report error to "
59 				   "http://bugzilla.gnome.org/ for the \"libgda\" product",
60 				   fa->contents);
61 			continue;
62 		}
63 		if (gda_tools_favorites_get (bfav, atoi (fa->contents + 5), &qfa, NULL)) {
64 			GdaSet *params;
65 			GSList *plist;
66 			GdaBatch *batch;
67 			GdaStatement *stmt = NULL;
68 			GdaSqlParser *parser;
69 			const gchar *remain;
70 			const GSList *stmt_list;
71 			gint nb_bound = 0;
72 
73 			parser = browser_connection_create_parser (bcnc);
74 			batch = gda_sql_parser_parse_string_as_batch (parser, qfa.contents, &remain, NULL);
75 			g_object_unref (parser);
76 			if (!batch) {
77 				gda_tools_favorites_reset_attributes (&qfa);
78 				continue;
79 			}
80 			stmt_list = gda_batch_get_statements (batch);
81 			for (plist = (GSList*) stmt_list; plist; plist = plist->next) {
82 				if (! gda_statement_is_useless (GDA_STATEMENT (plist->data))) {
83 					if (stmt)
84 						break;
85 					else
86 						stmt = g_object_ref (GDA_STATEMENT (plist->data));
87 				}
88 			}
89 			g_object_unref (batch);
90 			if (!stmt || plist) {
91 				gda_tools_favorites_reset_attributes (&qfa);
92 				continue;
93 			}
94 
95 			if (! gda_statement_get_parameters (stmt, &params, NULL) || !params) {
96 				g_object_unref (stmt);
97 				gda_tools_favorites_reset_attributes (&qfa);
98 				continue;
99 			}
100 			browser_connection_define_ui_plugins_for_stmt (bcnc, stmt, params);
101 
102 			for (plist = params->holders; plist; plist = plist->next) {
103 				/* try to find holder in @set */
104 				GdaHolder *req_holder, *in_holder;
105 				req_holder = GDA_HOLDER (plist->data);
106 				in_holder = gda_set_get_holder (set, gda_holder_get_id (req_holder));
107 				if (in_holder && gda_holder_set_bind (req_holder, in_holder, NULL)) {
108 					/* bound this holder to the oune found */
109 					nb_bound++;
110 				}
111 			}
112 
113 			if (nb_bound > 0) {
114 				/* at least 1 holder was found=> keep the action */
115 				ToolsFavoriteAction *act;
116 				act = g_new0 (ToolsFavoriteAction, 1);
117 				retlist = g_slist_insert_sorted (retlist, act,
118 								 (GCompareFunc) actions_sort_func);
119 				act->params = g_object_ref (params);
120 				act->id = fa->id;
121 				act->name = g_strdup (fa->name);
122 				act->stmt = g_object_ref (stmt);
123 				act->nb_bound = nb_bound;
124 
125 				/*g_print ("Action identified: ID=%d Bound=%d name=[%s] SQL=[%s]\n",
126 				  act->id, act->nb_bound,
127 				  act->name, qfa.contents);*/
128 			}
129 
130 			g_object_unref (stmt);
131 			g_object_unref (params);
132 			gda_tools_favorites_reset_attributes (&qfa);
133 		}
134 	}
135 	gda_tools_favorites_free_list (fav_list);
136 
137 	return retlist;
138 }
139 
140 /**
141  * gda_tools_favorites_free_action
142  * @action: (allow-none): a #ToolsFavoriteAction, or %NULL
143  *
144  * Frees @action
145  */
146 void
gda_tools_favorites_free_action(ToolsFavoriteAction * action)147 gda_tools_favorites_free_action (ToolsFavoriteAction *action)
148 {
149 	if (! action)
150 		return;
151 	g_free (action->name);
152 	if (action->stmt)
153 		g_object_unref (action->stmt);
154 	if (action->params)
155 		g_object_unref (action->params);
156 	g_free (action);
157 }
158 
159 /**
160  * gda_tools_favorites_free_actions_list
161  * @actions_list: (allow-none): a list of #ToolsFavoriteAction, or %NULL
162  *
163  * Free a list of #ToolsFavoriteAction (frees the list and each #ToolsFavoriteAction)
164  */
165 void
gda_tools_favorites_free_actions_list(GSList * actions_list)166 gda_tools_favorites_free_actions_list (GSList *actions_list)
167 {
168 	GSList *list;
169 	if (!actions_list)
170 		return;
171 
172 	for (list = actions_list; list; list = list->next)
173 		gda_tools_favorites_free_action ((ToolsFavoriteAction*) list->data);
174 	g_slist_free (actions_list);
175 }
176