1 /*
2  * Copyright (C) 2008 - 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 #ifndef __GDA_META_STRUCT_H_
21 #define __GDA_META_STRUCT_H_
22 
23 #include <glib-object.h>
24 #include <libgda/gda-data-model.h>
25 #include <libgda/gda-meta-store.h>
26 #include <libgda/gda-decl.h>
27 #include <libgda/gda-attributes-manager.h>
28 
29 G_BEGIN_DECLS
30 
31 #define GDA_TYPE_META_STRUCT          (gda_meta_struct_get_type())
32 #define GDA_META_STRUCT(obj)          G_TYPE_CHECK_INSTANCE_CAST (obj, gda_meta_struct_get_type(), GdaMetaStruct)
33 #define GDA_META_STRUCT_CLASS(klass)  G_TYPE_CHECK_CLASS_CAST (klass, gda_meta_struct_get_type (), GdaMetaStructClass)
34 #define GDA_IS_META_STRUCT(obj)       G_TYPE_CHECK_INSTANCE_TYPE (obj, gda_meta_struct_get_type ())
35 
36 /* error reporting */
37 extern GQuark gda_meta_struct_error_quark (void);
38 #define GDA_META_STRUCT_ERROR gda_meta_struct_error_quark ()
39 
40 typedef enum {
41 	GDA_META_STRUCT_UNKNOWN_OBJECT_ERROR,
42         GDA_META_STRUCT_DUPLICATE_OBJECT_ERROR,
43         GDA_META_STRUCT_INCOHERENCE_ERROR,
44 	GDA_META_STRUCT_XML_ERROR
45 } GdaMetaStructError;
46 
47 
48 /* struct for the object's data */
49 struct _GdaMetaStruct
50 {
51 	GObject                object;
52 	GdaMetaStructPrivate  *priv;
53 };
54 
55 /* struct for the object's class */
56 struct _GdaMetaStructClass
57 {
58 	GObjectClass              parent_class;
59 
60 	/*< private >*/
61 	/* Padding for future expansion */
62 	void (*_gda_reserved1) (void);
63 	void (*_gda_reserved2) (void);
64 	void (*_gda_reserved3) (void);
65 	void (*_gda_reserved4) (void);
66 };
67 
68 /**
69  * GdaMetaDbObjectType:
70  * @GDA_META_DB_UNKNOWN: unknown type
71  * @GDA_META_DB_TABLE: represents a table
72  * @GDA_META_DB_VIEW: represents a view
73  *
74  * Type of database object which can be handled as a #GdaMetaDbObject
75  */
76 typedef enum {
77 	GDA_META_DB_UNKNOWN,
78 	GDA_META_DB_TABLE,
79 	GDA_META_DB_VIEW
80 } GdaMetaDbObjectType;
81 
82 /*
83  * Controls which features are computed about database objects
84  */
85 /**
86  * GdaMetaStructFeature:
87  * @GDA_META_STRUCT_FEATURE_NONE: database objects only have their own attributes
88  * @GDA_META_STRUCT_FEATURE_FOREIGN_KEYS: foreign keys are computed for tables
89  * @GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES: for views, the tables they use are also computed
90  * @GDA_META_STRUCT_FEATURE_ALL: all the features are computed
91  *
92  * Controls which features are computed about database objects.
93  */
94 typedef enum {
95 	GDA_META_STRUCT_FEATURE_NONE              = 0,
96 	GDA_META_STRUCT_FEATURE_FOREIGN_KEYS      = 1 << 0,
97 	GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES = 1 << 1,
98 
99 	GDA_META_STRUCT_FEATURE_ALL               = GDA_META_STRUCT_FEATURE_FOREIGN_KEYS |
100 	                                            GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES
101 } GdaMetaStructFeature;
102 
103 /**
104  * GdaMetaSortType:
105  * @GDA_META_SORT_ALHAPETICAL: sort alphabetically
106  * @GDA_META_SORT_DEPENDENCIES: sort by dependencies
107  *
108  * Types of sorting
109  */
110 typedef enum {
111 	GDA_META_SORT_ALHAPETICAL,
112 	GDA_META_SORT_DEPENDENCIES
113 } GdaMetaSortType;
114 
115 /**
116  * GdaMetaTable:
117  * @columns: (element-type Gda.MetaTableColumn): list of #GdaMetaTableColumn structures, one for each column in the table
118  * @pk_cols_array: index of the columns part of the primary key for the table (WARNING: columns numbering
119  *                 here start at 0)
120  * @pk_cols_nb: size of the @pk_cols_array array
121  * @reverse_fk_list: (element-type Gda.MetaTableForeignKey): list of #GdaMetaTableForeignKey where the referenced table is this table
122  * @fk_list: (element-type Gda.MetaTableForeignKey): list of #GdaMetaTableForeignKey for this table
123  *
124  * This structure specifies a #GdaMetaDbObject to represent a table's specific attributes,
125  * its contents must not be modified.
126  *
127  * Note that in some cases, the columns cannot be determined for views, and in this case the
128  * @columns will be %NULL (this can be the case for example with SQLite where a view
129  * uses a function which is not natively provided by SQLite.
130  */
131 typedef struct {
132 	/*< public >*/
133 	GSList       *columns;
134 
135 	/* PK fields index */
136 	gint         *pk_cols_array;
137 	gint          pk_cols_nb;
138 
139 	/* Foreign keys */
140 	GSList       *reverse_fk_list; /* list of GdaMetaTableForeignKey where @depend_on == this GdaMetaDbObject */
141 	GSList       *fk_list; /* list of GdaMetaTableForeignKey where @meta_table == this GdaMetaDbObject */
142 
143 	/*< private >*/
144 	/* Padding for future expansion */
145 	gpointer _gda_reserved1;
146 	gpointer _gda_reserved2;
147 	gpointer _gda_reserved3;
148 	gpointer _gda_reserved4;
149 } GdaMetaTable;
150 
151 /**
152  * GdaMetaView:
153  * @table: a view is also a table as it has columns
154  * @view_def: views' definition
155  * @is_updatable: tells if the view's contents can be updated
156  *
157  * This structure specifies a #GdaMetaDbObject to represent a view's specific attributes,
158  * its contents must not be modified.
159  */
160 typedef struct {
161 	/*< public >*/
162 	GdaMetaTable  table;
163 	gchar        *view_def;
164 	gboolean      is_updatable;
165 
166 	/*< private >*/
167 	/* Padding for future expansion */
168 	gpointer _gda_reserved1;
169 	gpointer _gda_reserved2;
170 	gpointer _gda_reserved3;
171 	gpointer _gda_reserved4;
172 } GdaMetaView;
173 
174 /**
175  * GdaMetaDbObject:
176  * @extra: union for the actual object's contents, to be able to cast it using GDA_META_TABLE(), GDA_META_VIEW()
177  * @obj_type: the type of object (table, view)
178  * @outdated: set to %TRUE if the information in this #GdaMetaDbObject may be outdated because the #GdaMetaStore has been updated
179  * @obj_catalog: the catalog the object is in
180  * @obj_schema: the schema the object is in
181  * @obj_name: the object's name
182  * @obj_short_name: the shortest way to name the object
183  * @obj_full_name: the full name of the object (in the &lt;schema&gt;.&lt;nameagt; notation
184  * @obj_owner: object's owner
185  * @depend_list: (element-type Gda.MetaDbObject): list of #GdaMetaDbObject pointers on which this object depends (through foreign keys
186  *               or tables used for views)
187  *
188  * Struture to hold information about each database object (tables, views, ...),
189  * its contents must not be modified.
190  *
191  * Note: @obj_catalog, @obj_schema, @obj_name, @obj_short_name and @obj_full_name respect the
192  * <link linkend="information_schema:sql_identifiers">SQL identifiers</link> convention used in
193  * #GdaMetaStore objects. Before using these SQL identifiers, you should check the
194  * gda_sql_identifier_quote() to know if is it is necessary to surround by double quotes
195  * before using in an SQL statement.
196  */
197 typedef struct {
198 	/*< public >*/
199 	union {
200 		GdaMetaTable    meta_table;
201 		GdaMetaView     meta_view;
202 	}                       extra;
203 	GdaMetaDbObjectType     obj_type;
204 	gboolean                outdated;
205 	gchar                  *obj_catalog;
206 	gchar                  *obj_schema;
207 	gchar                  *obj_name;
208 	gchar                  *obj_short_name;
209 	gchar                  *obj_full_name;
210 	gchar                  *obj_owner;
211 
212 	GSList                 *depend_list;
213 
214 	/*< private >*/
215 	/* Padding for future expansion */
216 	gpointer _gda_reserved1;
217 	gpointer _gda_reserved2;
218 	gpointer _gda_reserved3;
219 	gpointer _gda_reserved4;
220 } GdaMetaDbObject;
221 
222 /**
223  * GDA_META_DB_OBJECT:
224  * @dbo: a pointer
225  *
226  * Casts @dbo to a #GdaMetaDbObject, no check is made on the validity of @dbo
227  *
228  * Returns: a pointer to a #GdaMetaDbObject
229  */
230 #define GDA_META_DB_OBJECT(dbo) ((GdaMetaDbObject*)(dbo))
231 
232 /**
233  * GDA_META_TABLE:
234  * @dbo: a pointer
235  *
236  * Casts @dbo to a #GdaMetaTable, no check is made on the validity of @dbo
237  *
238  * Returns: a pointer to a #GdaMetaTable
239  */
240 #define GDA_META_TABLE(dbobj) (&((dbobj)->extra.meta_table))
241 
242 /**
243  * GDA_META_VIEW:
244  * @dbo: a pointer
245  *
246  * Casts @dbo to a #GdaMetaView, no check is made on the validity of @dbo
247  *
248  * Returns: a pointer to a #GdaMetaView
249  */
250 #define GDA_META_VIEW(dbobj) (&((dbobj)->extra.meta_view))
251 
252 /**
253  * GdaMetaTableColumn:
254  * @column_name: the column's name
255  * @column_type: the column's DBMS's type
256  * @gtype: the detected column's #GType
257  * @pkey: tells if the column is part of a primary key
258  * @nullok: tells if the column can be %NULL
259  * @default_value: (allow-none): the column's default value, represented as a valid SQL value (surrounded by simple quotes for strings, ...), or %NULL if column has no default value
260  *
261  * This structure represents a table of view's column, its contents must not be modified.
262  */
263 typedef struct {
264 	/*< public >*/
265 	gchar        *column_name;
266 	gchar        *column_type;
267 	GType         gtype;
268 	gboolean      pkey;
269 	gboolean      nullok;
270 	gchar        *default_value;
271 
272 	/*< private >*/
273 	/* Padding for future expansion */
274 	gpointer _gda_reserved1;
275 	gpointer _gda_reserved2;
276 	gpointer _gda_reserved3;
277 	gpointer _gda_reserved4;
278 } GdaMetaTableColumn;
279 
280 /**
281  * GDA_META_TABLE_COLUMN:
282  * @col: a pointer
283  *
284  * Casts @col to a #GdaMetaTableColumn, no check is made
285  *
286  * Returns: @col, casted to a #GdaMetaTableColumn
287  */
288 #define GDA_META_TABLE_COLUMN(col) ((GdaMetaTableColumn*)(col))
289 
290 const GValue *gda_meta_table_column_get_attribute (GdaMetaTableColumn *tcol, const gchar *attribute);
291 void          gda_meta_table_column_set_attribute (GdaMetaTableColumn *tcol, const gchar *attribute, const GValue *value,
292 						   GDestroyNotify destroy);
293 /**
294  * gda_meta_table_column_set_attribute_static:
295  * @column: a #GdaMetaTableColumn
296  * @attribute: attribute's name
297  * @value: (allow-none): a #GValue, or %NULL
298  *
299  * This function is similar to gda_meta_table_column_set_attribute() but for static strings
300  */
301 #define gda_meta_table_column_set_attribute_static(column,attribute,value) gda_meta_table_column_set_attribute((column),(attribute),(value),NULL)
302 
303 void          gda_meta_table_column_foreach_attribute (GdaMetaTableColumn *tcol, GdaAttributesManagerFunc func, gpointer data);
304 
305 /**
306  * GdaMetaForeignKeyPolicy:
307  * @GDA_META_FOREIGN_KEY_UNKNOWN: unspecified policy
308  * @GDA_META_FOREIGN_KEY_NONE: not enforced policy
309  * @GDA_META_FOREIGN_KEY_NO_ACTION: return an error, no action taken
310  * @GDA_META_FOREIGN_KEY_RESTRICT: same as @GDA_META_FOREIGN_KEY_NO_ACTION, not deferrable
311  * @GDA_META_FOREIGN_KEY_CASCADE: policy is to delete any rows referencing the deleted row, or update the value of the referencing column to the new value of the referenced column, respectively
312  * @GDA_META_FOREIGN_KEY_SET_NULL: policy is to set the referencing column to NULL
313  * @GDA_META_FOREIGN_KEY_SET_DEFAULT: policy is to set the referencing column to its default value
314  *
315  * Defines the filtering policy of a foreign key when invoked on an UPDATE
316  * or DELETE operation.
317  */
318 typedef enum {
319 	GDA_META_FOREIGN_KEY_UNKNOWN,
320 	GDA_META_FOREIGN_KEY_NONE,
321 	GDA_META_FOREIGN_KEY_NO_ACTION,
322 	GDA_META_FOREIGN_KEY_RESTRICT,
323 	GDA_META_FOREIGN_KEY_CASCADE,
324 	GDA_META_FOREIGN_KEY_SET_NULL,
325 	GDA_META_FOREIGN_KEY_SET_DEFAULT
326 } GdaMetaForeignKeyPolicy;
327 
328 /**
329  * GdaMetaTableForeignKey:
330  * @meta_table: the #GdaMetaDbObject for which this structure represents a foreign key
331  * @depend_on: the #GdaMetaDbObject which is referenced by the foreign key
332  * @cols_nb: the size of the @fk_cols_array, @fk_names_array, @ref_pk_cols_array and @ref_pk_names_array arrays
333  * @fk_cols_array: the columns' indexes in @meta_table which participate in the constraint (WARNING: columns numbering
334  *                 here start at 1)
335  * @fk_names_array: the columns' names in @meta_table which participate in the constraint
336  * @ref_pk_cols_array: the columns' indexes in @depend_on which participate in the constraint (WARNING: columns numbering
337  *                 here start at 1)
338  * @ref_pk_names_array: the columns' names in @depend_on which participate in the constraint
339  *
340  * This structure represents a foreign key constraint, its contents must not be modified.
341  */
342 typedef struct {
343 	/*< public >*/
344 	GdaMetaDbObject  *meta_table;
345 	GdaMetaDbObject  *depend_on;
346 
347 	gint              cols_nb;
348 	gint             *fk_cols_array; /* FK fields index */
349 	gchar           **fk_names_array; /* FK fields names */
350 	gint             *ref_pk_cols_array; /* Ref PK fields index */
351 	gchar           **ref_pk_names_array; /* Ref PK fields names */
352 
353 	/*< private >*/
354 	GdaMetaForeignKeyPolicy on_update_policy; /* pointer containing the GdaMetaForeignKeyPolicy integer
355 					     * to keep ABI from 4.0, use GINT_TO_POINTER and
356 					     * GPOINTER_TO_INT */
357 	GdaMetaForeignKeyPolicy on_delete_policy; /* pointer containing the GdaMetaForeignKeyPolicy integer
358 					     * to keep ABI from 4.0, use GINT_TO_POINTER and
359 					     * GPOINTER_TO_INT */
360 	gboolean          declared; /* pointer to a boolean to keep ABI from 4.0.
361 				     * Any non NULL if FK has been declared in meta data */
362 
363 	/*< public >*/
364 	gchar            *fk_name;
365 
366 	/*< private >*/
367 	/* Padding for future expansion */
368 	gpointer _gda_reserved1;
369 	gpointer _gda_reserved2;
370 	gpointer _gda_reserved3;
371 	gpointer _gda_reserved4;
372 } GdaMetaTableForeignKey;
373 /**
374  * GDA_META_TABLE_FOREIGN_KEY:
375  * @fk: a pointer
376  *
377  * Casts @fk to a #GdaMetaTableForeignKey (no check is actuelly being done on @fk's validity)
378  *
379  * Returns: @col, casted to a #GdaMetaTableForeignKey
380  */
381 #define GDA_META_TABLE_FOREIGN_KEY(fk) ((GdaMetaTableForeignKey*)(fk))
382 
383 /**
384  * GDA_META_TABLE_FOREIGN_KEY_ON_UPDATE_POLICY:
385  * @fk: a pointer to a #GdaMetaTableForeignKey
386  *
387  * Tells the actual policy implemented by @fk when used in the context of an UPDATE.
388  *
389  * Returns: the policy as a #GdaMetaForeignKeyPolicy
390  */
391 #define GDA_META_TABLE_FOREIGN_KEY_ON_UPDATE_POLICY(fk) (((GdaMetaTableForeignKey*)(fk))->on_update_policy)
392 
393 /**
394  * GDA_META_TABLE_FOREIGN_KEY_ON_DELETE_POLICY:
395  * @fk: a pointer to a #GdaMetaTableForeignKey
396  *
397  * Tells the actual policy implemented by @fk when used in the context of a DELETE.
398  *
399  * Returns: the policy as a #GdaMetaForeignKeyPolicy
400  */
401 #define GDA_META_TABLE_FOREIGN_KEY_ON_DELETE_POLICY(fk) (((GdaMetaTableForeignKey*)(fk))->on_delete_policy)
402 
403 /**
404  * GDA_META_TABLE_FOREIGN_KEY_IS_DECLARED:
405  * @fk: a pointer to a #GdaMetaTableForeignKey
406  *
407  * Tells if @fk is an actual foreign key defined in the database's schema, or if it is an indication which
408  * has been added to help Libgda understand the database schema.
409  *
410  * Returns: %TRUE if @fk has been declared in the database's meta data and %FALSE if @fk is an actual foreign key defined in the database's schema
411  */
412 #define GDA_META_TABLE_FOREIGN_KEY_IS_DECLARED(fk) (((GdaMetaTableForeignKey*)(fk))->declared)
413 
414 /**
415  * SECTION:gda-meta-struct
416  * @short_description: In memory representation of some database objects
417  * @title: GdaMetaStruct
418  * @stability: Stable
419  * @see_also: #GdaMetaStore
420  *
421  * The #GdaMetaStruct object reads data from a #GdaMetaStore object and
422  *  creates an easy to use in memory representation for some database objects. For example one can easily
423  *  analyze the columns of a table (or its foreign keys) using a #GdaMetaStruct.
424  *
425  *  When created, the new #GdaMetaStruct object is empty (it does not have any information about any database object).
426  *  Information about database objects is computed upon request using the gda_meta_struct_complement() method. Information
427  *  about individual database objects is represented by #GdaMetaDbObject structures, which can be obtained using
428  *  gda_meta_struct_get_db_object() or gda_meta_struct_get_all_db_objects().
429  *
430  *  Note that the #GdaMetaDbObject structures may change or may be removed or replaced by others, so it not
431  *  advised to keep pointers to these structures: pointers to these structures should be considered valid
432  *  as long as gda_meta_struct_complement() and other similar functions have not been called.
433  *
434  *  In the following code sample, one prints the columns names and types of a table:
435  *  <programlisting>
436  *GdaMetaStruct *mstruct;
437  *GdaMetaDbObject *dbo;
438  *GValue *catalog, *schema, *name;
439  *
440  * // Define name (and optionnally catalog and schema)
441  *[...]
442  *
443  *mstruct = gda_meta_struct_new ();
444  *gda_meta_struct_complement (mstruct, store, GDA_META_DB_TABLE, catalog, schema, name, NULL);
445  *dbo = gda_meta_struct_get_db_object (mstruct, catalog, schema, name);
446  *if (!dbo)
447  *        g_print ("Table not found\n");
448  *else {
449  *        GSList *list;
450  *        for (list = GDA_META_TABLE (dbo)->columns; list; list = list->next) {
451  *                GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
452  *                g_print ("COLUMN: %s (%s)\n", tcol->column_name, tcol->column_type);
453  *        }
454  *}
455  *gda_meta_struct_free (mstruct);
456  *  </programlisting>
457  *  If now the database object type is not known, one can use the following code:
458  *  <programlisting>
459  *GdaMetaStruct *mstruct;
460  *GdaMetaDbObject *dbo;
461  *GValue *catalog, *schema, *name;
462  *
463  * // Define name (and optionnally catalog and schema)
464  *[...]
465  *
466  *mstruct = gda_meta_struct_new ();
467  *gda_meta_struct_complement (mstruct, store, GDA_META_DB_UNKNOWN, catalog, schema, name, NULL);
468  *dbo = gda_meta_struct_get_db_object (mstruct, catalog, schema, name);
469  *if (!dbo)
470  *        g_print ("Object not found\n");
471  *else {
472  *        if ((dbo->obj_type == GDA_META_DB_TABLE) || (dbo->obj_type == GDA_META_DB_VIEW)) {
473  *                if (dbo->obj_type == GDA_META_DB_TABLE)
474  *                        g_print ("Is a table\n");
475  *                else if (dbo->obj_type == GDA_META_DB_VIEW) {
476  *                        g_print ("Is a view, definition is:\n");
477  *                        g_print ("%s\n", GDA_META_VIEW (dbo)->view_def);
478  *                }
479  *
480  *                GSList *list;
481  *                for (list = GDA_META_TABLE (dbo)->columns; list; list = list->next) {
482  *                        GdaMetaTableColumn *tcol = GDA_META_TABLE_COLUMN (list->data);
483  *                        g_print ("COLUMN: %s (%s)\n", tcol->column_name, tcol->column_type);
484  *                }
485  *        }
486  *        else
487  *                g_print ("Not a table or a view\n");
488  *}
489  *gda_meta_struct_free (mstruct);
490  *  </programlisting>
491  */
492 
493 GType               gda_meta_struct_get_type           (void) G_GNUC_CONST;
494 GdaMetaStruct      *gda_meta_struct_new                (GdaMetaStore *store, GdaMetaStructFeature features);
495 gboolean            gda_meta_struct_load_from_xml_file (GdaMetaStruct *mstruct, const gchar *catalog,
496 							const gchar *schema,
497 							const gchar *xml_spec_file, GError **error);
498 GdaMetaDbObject    *gda_meta_struct_complement         (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
499 							const GValue *catalog, const GValue *schema, const GValue *name,
500 							GError **error);
501 gboolean            gda_meta_struct_complement_schema  (GdaMetaStruct *mstruct,
502 							const GValue *catalog, const GValue *schema, GError **error);
503 gboolean            gda_meta_struct_complement_default (GdaMetaStruct *mstruct, GError **error);
504 gboolean            gda_meta_struct_complement_all     (GdaMetaStruct *mstruct, GError **error);
505 gboolean            gda_meta_struct_complement_depend  (GdaMetaStruct *mstruct, GdaMetaDbObject *dbo,
506 							GError **error);
507 
508 gboolean            gda_meta_struct_sort_db_objects    (GdaMetaStruct *mstruct, GdaMetaSortType sort_type, GError **error);
509 GSList             *gda_meta_struct_get_all_db_objects (GdaMetaStruct *mstruct);
510 GdaMetaDbObject    *gda_meta_struct_get_db_object      (GdaMetaStruct *mstruct,
511 						        const GValue *catalog, const GValue *schema, const GValue *name);
512 GdaMetaTableColumn *gda_meta_struct_get_table_column   (GdaMetaStruct *mstruct, GdaMetaTable *table,
513 						        const GValue *col_name);
514 
515 typedef enum {
516 	GDA_META_GRAPH_COLUMNS = 1 << 0
517 } GdaMetaGraphInfo;
518 
519 gchar              *gda_meta_struct_dump_as_graph      (GdaMetaStruct *mstruct, GdaMetaGraphInfo info, GError **error);
520 
521 G_END_DECLS
522 
523 #endif
524