1 /*
2  * Copyright (C) 2009 - 2011 Vivien Malerba <malerba@gnome-db.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library 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 GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19 
20 #include <gda-repetitive-statement.h>
21 #include <libgda/gda-set.h>
22 #include <libgda/gda-holder.h>
23 #include <libgda/gda-connection.h>
24 
25 typedef struct _GdaRepetitiveStatementPrivate GdaRepetitiveStatementPrivate;
26 struct _GdaRepetitiveStatementPrivate
27 {
28 	GdaStatement* statement;
29 	GSList* values_sets; /* list of GdaSet pointers, objects referenced here */
30 };
31 
32 #define GDA_REPETITIVE_STATEMENT_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDA_TYPE_REPETITIVE_STATEMENT, GdaRepetitiveStatementPrivate))
33 
34 enum {
35 	PROP_0,
36 	PROP_STATEMENT
37 };
38 
39 G_DEFINE_TYPE (GdaRepetitiveStatement, gda_repetitive_statement, G_TYPE_OBJECT);
40 
41 static void
gda_repetitive_statement_init(GdaRepetitiveStatement * object)42 gda_repetitive_statement_init (GdaRepetitiveStatement *object)
43 {
44 	GdaRepetitiveStatementPrivate *priv;
45 
46 	priv = GDA_REPETITIVE_STATEMENT_PRIVATE (object);
47 
48 	priv->statement = NULL;
49 	priv->values_sets = NULL;
50 }
51 
52 static void
gda_repetitive_statement_finalize(GObject * object)53 gda_repetitive_statement_finalize (GObject *object)
54 {
55 	GdaRepetitiveStatementPrivate *priv;
56 
57 	priv = GDA_REPETITIVE_STATEMENT_PRIVATE (object);
58 
59 	g_object_unref (priv->statement);
60 	g_slist_foreach (priv->values_sets, (GFunc) g_object_unref, NULL);
61 	g_slist_free (priv->values_sets);
62 
63 	G_OBJECT_CLASS (gda_repetitive_statement_parent_class)->finalize (object);
64 }
65 
66 static void
gda_repetitive_statement_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)67 gda_repetitive_statement_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
68 {
69 	GdaRepetitiveStatementPrivate *priv;
70 
71 	g_return_if_fail (GDA_IS_REPETITIVE_STATEMENT (object));
72 
73 	priv = GDA_REPETITIVE_STATEMENT_PRIVATE (object);
74 	switch (prop_id) {
75 	case PROP_STATEMENT:
76 		priv->statement = g_value_dup_object (value);
77 		break;
78 	default:
79 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
80 		break;
81 	}
82 }
83 
84 static void
gda_repetitive_statement_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)85 gda_repetitive_statement_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
86 {
87 	GdaRepetitiveStatementPrivate *priv;
88 
89 	g_return_if_fail (GDA_IS_REPETITIVE_STATEMENT (object));
90 
91 	priv = GDA_REPETITIVE_STATEMENT_PRIVATE (object);
92 	switch (prop_id) {
93 	case PROP_STATEMENT:
94 		g_value_set_object (value, priv->statement);
95 		break;
96 	default:
97 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
98 		break;
99 	}
100 }
101 
102 static void
gda_repetitive_statement_class_init(GdaRepetitiveStatementClass * klass)103 gda_repetitive_statement_class_init (GdaRepetitiveStatementClass *klass)
104 {
105 	GObjectClass* object_class = G_OBJECT_CLASS (klass);
106 
107 	g_type_class_add_private (klass, sizeof (GdaRepetitiveStatementPrivate));
108 
109 	object_class->finalize = gda_repetitive_statement_finalize;
110 	object_class->set_property = gda_repetitive_statement_set_property;
111 	object_class->get_property = gda_repetitive_statement_get_property;
112 
113 	g_object_class_install_property (object_class,
114 	                                 PROP_STATEMENT,
115 	                                 g_param_spec_object ("statement",
116 	                                                      "stmt",
117 	                                                      "Statement to Execute",
118 	                                                      GDA_TYPE_STATEMENT,
119 	                                                      G_PARAM_WRITABLE | G_PARAM_READABLE | G_PARAM_CONSTRUCT_ONLY));
120 }
121 
122 /**
123  * gda_repetitive_statement_new:
124  * @stmt: a #GdaStatement object
125  *
126  * Creates a new #GdaRepetitiveStatement object which, when executed, will execute @stmt once for all
127  * the values set which will have been defined using gda_repetitive_statement_append_set().
128  * Use gda_connection_repetitive_statement_execute() to actually execute it.
129  *
130  * Returns: a new #GdaRepetitiveStatement object
131  *
132  * Since: 4.2
133  */
134 GdaRepetitiveStatement*
gda_repetitive_statement_new(GdaStatement * stmt)135 gda_repetitive_statement_new (GdaStatement *stmt)
136 {
137 	GdaRepetitiveStatement *rstmt;
138 
139 	rstmt = GDA_REPETITIVE_STATEMENT (g_object_new (GDA_TYPE_REPETITIVE_STATEMENT,
140 							"statement", stmt, NULL));
141 
142 	return rstmt;
143 }
144 
145 /**
146  * gda_repetitive_statement_get_template_set:
147  * @rstmt: a #GdaRepetitiveStatement object
148  * @set: a place to store the returned template set
149  * @error: (allow-none): a place to store error, or %NULL
150  *
151  * Gets a new #GdaSet object with the parameters used by the template statement in the
152  * @rstmt object.
153  *
154  * Use this object with gda_repetitive_statement_append_set().
155  *
156  * Returns: %TRUE on success, %FALSE on error
157  *
158  * Since: 4.2
159  */
160 gboolean
gda_repetitive_statement_get_template_set(GdaRepetitiveStatement * rstmt,GdaSet ** set,GError ** error)161 gda_repetitive_statement_get_template_set (GdaRepetitiveStatement *rstmt, GdaSet **set, GError **error)
162 {
163 	GdaRepetitiveStatementPrivate *priv;
164 
165 	priv = GDA_REPETITIVE_STATEMENT_PRIVATE (rstmt);
166 
167 	return gda_statement_get_parameters (priv->statement, set, error);
168 }
169 
170 /**
171  * gda_repetitive_statement_append_set:
172  * @rstmt: a #GdaRepetitiveStatement object
173  * @values: a #GdaSet object with the values to be used
174  * @make_copy: %TRUE if @values is copied, and %FALSE if @values is only ref'ed
175  *
176  * Specifies that @rstmt be executed one time with the values contained in @values.
177  *
178  * A new #GdaSet to be used as the @values argument can be obtained using
179  * gda_repetitive_statement_get_template_set().
180  *
181  * Returns: a new #GdaRepetitiveStatement object
182  *
183  * Since: 4.2
184  */
185 gboolean
gda_repetitive_statement_append_set(GdaRepetitiveStatement * rstmt,GdaSet * values,gboolean make_copy)186 gda_repetitive_statement_append_set (GdaRepetitiveStatement *rstmt, GdaSet *values, gboolean make_copy)
187 {
188 	GdaRepetitiveStatementPrivate *priv;
189 	GdaSet *set;
190 
191 	g_return_val_if_fail (GDA_IS_REPETITIVE_STATEMENT(rstmt), FALSE);
192 	g_return_val_if_fail (GDA_IS_SET (values), FALSE);
193 
194 	priv = GDA_REPETITIVE_STATEMENT_PRIVATE (rstmt);
195 
196 	if (make_copy)
197 		set = gda_set_copy (values);
198 	else
199 		set = g_object_ref (values);
200 	priv->values_sets = g_slist_prepend (priv->values_sets, set);
201 
202 	return TRUE;
203 }
204 
205 /**
206  * gda_repetitive_statement_get_all_sets:
207  * @rstmt: a #GdaRepetitiveStatement object
208  *
209  * Get all the values sets which will have been added using gda_repetitive_statement_append_set().
210  *
211  * Returns: (transfer container) (element-type GdaSet): a new #GSList of #GdaSet objects (free with g_slist_free()).
212  *
213  * Since: 4.2
214  */
215 GSList*
gda_repetitive_statement_get_all_sets(GdaRepetitiveStatement * rstmt)216 gda_repetitive_statement_get_all_sets (GdaRepetitiveStatement *rstmt)
217 {
218 	GdaRepetitiveStatementPrivate *priv;
219 
220 	priv = GDA_REPETITIVE_STATEMENT_PRIVATE (rstmt);
221 
222 	return g_slist_copy (g_slist_reverse (priv->values_sets));
223 }
224