1 /*
2 * Copyright (C) 2008 - 2011 Vivien Malerba <malerba@gnome-db.org>
3 * Copyright (C) 2009 Bas Driessen <bas.driessen@xobas.com>
4 * Copyright (C) 2010 Murray Cumming <murrayc@murrayc.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include <string.h>
23 #include <libgda/sql-parser/gda-statement-struct-pspec.h>
24 #include <libgda/sql-parser/gda-statement-struct-parts.h>
25 #include <libgda/sql-parser/gda-statement-struct-util.h>
26 #include <libgda/gda-util.h>
27
28 /**
29 * gda_sql_param_spec_take_name:
30 * @pspec: a #GdaSqlParamSpec pointer
31 * @value: (transfer full): a G_TYPE_STRING #GValue
32 *
33 * Sets @pspec's name. @value's ownership is transferred to
34 * @pspec (which means @pspec is then responsible for freeing it when no longer needed).
35 */
36 void
gda_sql_param_spec_take_name(GdaSqlParamSpec * pspec,GValue * value)37 gda_sql_param_spec_take_name (GdaSqlParamSpec *pspec, GValue *value)
38 {
39 if (pspec->name) {
40 g_free (pspec->name);
41 pspec->name = NULL;
42 }
43 if (value) {
44 pspec->name = _remove_quotes (g_value_dup_string (value));
45 gda_value_free (value);
46 }
47 }
48
49 /**
50 * gda_sql_param_spec_take_descr:
51 * @pspec: a #GdaSqlParamSpec pointer
52 * @value: (transfer full): a G_TYPE_STRING #GValue
53 *
54 * Sets @pspec's description. @value's ownership is transferred to
55 * @pspec (which means @pspec is then responsible for freeing it when no longer needed).
56 */
57 void
gda_sql_param_spec_take_descr(GdaSqlParamSpec * pspec,GValue * value)58 gda_sql_param_spec_take_descr (GdaSqlParamSpec *pspec, GValue *value)
59 {
60 if (pspec->descr) {
61 g_free (pspec->descr);
62 pspec->descr = NULL;
63 }
64 if (value) {
65 pspec->descr = _remove_quotes (g_value_dup_string (value));
66 gda_value_free (value);
67 }
68 }
69
70 /**
71 * gda_sql_param_spec_take_nullok:
72 * @pspec: a #GdaSqlParamSpec pointer
73 * @value: (transfer full): a G_TYPE_STRING #GValue.
74 *
75 * Sets @pspec's ability of being NULL. @value's ownership is transferred to
76 * @pspec (which means @pspec is then responsible for freeing it when no longer needed).
77 *
78 * If @value's string starts by 't' or 'T' then @pspec will be allowed to be %NULL
79 */
80 void
gda_sql_param_spec_take_nullok(GdaSqlParamSpec * pspec,GValue * value)81 gda_sql_param_spec_take_nullok (GdaSqlParamSpec *pspec, GValue *value)
82 {
83 pspec->nullok = FALSE;
84 if (value) {
85 gchar *str = (gchar *) g_value_get_string (value);
86 if (str) {
87 _remove_quotes (str);
88 if ((*str == 't') || (*str == 'T'))
89 pspec->nullok = TRUE;
90 }
91 gda_value_free (value);
92 }
93 }
94
95 /**
96 * gda_sql_param_spec_take_type:
97 * @pspec: a #GdaSqlParamSpec pointer
98 * @value: (transfer full): a G_TYPE_STRING #GValue
99 *
100 * Sets @pspec's data type. @value's ownership is transferred to
101 * @pspec (which means @pspec is then responsible for freeing it when no longer needed).
102 *
103 * @value must represent a data type, as understood by gda_g_type_from_string().
104 */
105 void
gda_sql_param_spec_take_type(GdaSqlParamSpec * pspec,GValue * value)106 gda_sql_param_spec_take_type (GdaSqlParamSpec *pspec, GValue *value)
107 {
108 pspec->g_type = GDA_TYPE_NULL;
109 if (value) {
110 gchar *tmp;
111 tmp = _remove_quotes (g_value_dup_string (value));
112 gda_value_free (value);
113
114 pspec->g_type = gda_g_type_from_string (tmp);
115 g_free (tmp);
116 if (pspec->g_type == G_TYPE_INVALID)
117 pspec->g_type = GDA_TYPE_NULL;
118 }
119 }
120
121 /**
122 * gda_sql_param_spec_new:
123 * @value: (transfer full): a G_TYPE_STRING #GValue
124 *
125 * @value must contain a string representing a variable, see the documentation associated to the
126 * #GdaSqlParser object.
127 *
128 * @value is destroyed by this function.
129 *
130 * Returns: a new #GdaSqlParamSpec
131 */
132 GdaSqlParamSpec *
gda_sql_param_spec_new(GValue * value)133 gda_sql_param_spec_new (GValue *value)
134 {
135 GdaSqlParamSpec *pspec;
136
137 pspec =g_new0 (GdaSqlParamSpec, 1);
138 pspec->is_param = TRUE;
139 pspec->nullok = FALSE;
140 pspec->g_type = GDA_TYPE_NULL;
141
142 if (value) {
143 gchar *str = (gchar *) g_value_get_string (value);
144 gchar *ptr;
145 gint part; /* 0 for name, 1 for type and 2 for NULL */
146 ptr = str;
147 for (part = 0; *ptr && (part < 3); part++) {
148 gchar old;
149 for (; *ptr && ((*ptr != ':') || (*(ptr+1) != ':')); ptr++);
150 old = *ptr;
151 *ptr = 0;
152 switch (part) {
153 case 0:
154 g_free (pspec->name);
155 pspec->name = g_strdup (str);
156 break;
157 case 1:
158 pspec->g_type = gda_g_type_from_string (str);
159 if (pspec->g_type == G_TYPE_INVALID)
160 pspec->g_type = GDA_TYPE_NULL;
161 break;
162 case 2:
163 pspec->nullok = (*str == 'n') || (*str == 'N') ? TRUE : FALSE;
164 break;
165 }
166 *ptr = old;
167 if (*ptr) {
168 ptr +=2;
169 str = ptr;
170 }
171 }
172 gda_value_free (value);
173 }
174
175 return pspec;
176 }
177
178 /**
179 * gda_sql_param_spec_copy:
180 * @pspec: #GdaSqlParamSpec pointer
181 *
182 * Creates a copy of @pspec.
183 *
184 * Returns: a new #GdaSqlParamSpec
185 */
186 GdaSqlParamSpec *
gda_sql_param_spec_copy(GdaSqlParamSpec * pspec)187 gda_sql_param_spec_copy (GdaSqlParamSpec *pspec)
188 {
189 GdaSqlParamSpec *copy;
190 if (!pspec) return NULL;
191
192 copy = g_new0 (GdaSqlParamSpec, 1);
193 if (pspec->name)
194 copy->name = g_strdup (pspec->name);
195 if (pspec->descr)
196 copy->descr = g_strdup (pspec->descr);
197 copy->g_type = pspec->g_type;
198 copy->is_param = pspec->is_param;
199 copy->nullok = pspec->nullok;
200
201 return copy;
202 }
203
204 /**
205 * gda_sql_param_spec_free:
206 * @pspec: #GdaSqlParamSpec pointer
207 *
208 * Destroys @pspec.
209 */
210 void
gda_sql_param_spec_free(GdaSqlParamSpec * pspec)211 gda_sql_param_spec_free (GdaSqlParamSpec *pspec)
212 {
213 if (!pspec) return;
214
215 g_free (pspec->name);
216 g_free (pspec->descr);
217 g_free (pspec);
218 }
219
220 /**
221 * gda_sql_param_spec_serialize:
222 * @pspec: a #GdaSqlParamSpec pointer
223 *
224 * Creates a new string representing @pspec.
225 *
226 * Returns: a new string.
227 */
228 gchar *
gda_sql_param_spec_serialize(GdaSqlParamSpec * pspec)229 gda_sql_param_spec_serialize (GdaSqlParamSpec *pspec)
230 {
231 GString *string;
232 gchar *str;
233
234 if (!pspec)
235 return NULL;
236
237 string = g_string_new ("{");
238 str = _json_quote_string (pspec->name);
239 g_string_append_printf (string, "\"name\":%s", str);
240 g_free (str);
241
242
243 str = _json_quote_string (pspec->descr);
244 g_string_append_printf (string, ",\"descr\":%s", str);
245 g_free (str);
246
247 if (pspec->g_type != GDA_TYPE_NULL) {
248 str = _json_quote_string (gda_g_type_to_string (pspec->g_type));
249 g_string_append_printf (string, ",\"type\":%s", str);
250 g_free (str);
251 }
252 else
253 g_string_append_printf (string, ",\"type\":null");
254
255 g_string_append_printf (string, ",\"is_param\":%s", pspec->is_param ? "true" : "false");
256 g_string_append_printf (string, ",\"nullok\":%s", pspec->nullok ? "true" : "false");
257 g_string_append_c (string, '}');
258 str = string->str;
259 g_string_free (string, FALSE);
260 return str;
261 }
262
263