[libgda/gtk3] GdaMetaStruct now reports foreign keys policy
- From: Vivien Malerba <vivien src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda/gtk3] GdaMetaStruct now reports foreign keys policy
- Date: Wed, 9 Feb 2011 20:34:31 +0000 (UTC)
commit 46f4b41702b5e2d54f0c8caea4ae7a6f6a0327f1
Author: Vivien Malerba <malerba gnome-db org>
Date: Tue Jan 25 21:21:10 2011 +0100
GdaMetaStruct now reports foreign keys policy
also improved documentation
doc/C/libgda-sections.txt | 4 +
doc/C/tmpl/gda-meta-struct.sgml | 43 ++++++++++++-
libgda/gda-meta-struct.c | 59 +++++++++++++++++-
libgda/gda-meta-struct.h | 129 ++++++++++++++++++++++++++++++++++++---
4 files changed, 218 insertions(+), 17 deletions(-)
---
diff --git a/doc/C/libgda-sections.txt b/doc/C/libgda-sections.txt
index 1495dcc..374ed80 100644
--- a/doc/C/libgda-sections.txt
+++ b/doc/C/libgda-sections.txt
@@ -1374,8 +1374,12 @@ gda_meta_table_column_get_attribute
gda_meta_table_column_set_attribute
gda_meta_table_column_set_attribute_static
gda_meta_table_column_foreach_attribute
+GdaMetaForeignKeyPolicy
GdaMetaTableForeignKey
GDA_META_TABLE_FOREIGN_KEY
+GDA_META_TABLE_FOREIGN_KEY_ON_UPDATE_POLICY
+GDA_META_TABLE_FOREIGN_KEY_ON_DELETE_POLICY
+GDA_META_TABLE_FOREIGN_KEY_IN_SCHEMA
GDA_META_STRUCT_ERROR
gda_meta_struct_new
gda_meta_struct_complement
diff --git a/doc/C/tmpl/gda-meta-struct.sgml b/doc/C/tmpl/gda-meta-struct.sgml
index f43e10f..90864c5 100644
--- a/doc/C/tmpl/gda-meta-struct.sgml
+++ b/doc/C/tmpl/gda-meta-struct.sgml
@@ -161,7 +161,7 @@ gda_meta_struct_free (mstruct);
</para>
- x:
+ dbo:
<!-- ##### MACRO GDA_META_TABLE ##### -->
@@ -217,7 +217,7 @@ gda_meta_struct_free (mstruct);
</para>
- x:
+ col:
<!-- ##### FUNCTION gda_meta_table_column_get_attribute ##### -->
@@ -261,6 +261,19 @@ gda_meta_struct_free (mstruct);
@data:
+<!-- ##### ENUM GdaMetaForeignKeyPolicy ##### -->
+<para>
+
+</para>
+
+ GDA_META_FOREIGN_KEY_UNKNOWN:
+ GDA_META_FOREIGN_KEY_NONE:
+ GDA_META_FOREIGN_KEY_NO_ACTION:
+ GDA_META_FOREIGN_KEY_RESTRICT:
+ GDA_META_FOREIGN_KEY_CASCADE:
+ GDA_META_FOREIGN_KEY_SET_NULL:
+ GDA_META_FOREIGN_KEY_SET_DEFAULT:
+
<!-- ##### STRUCT GdaMetaTableForeignKey ##### -->
<para>
@@ -279,7 +292,31 @@ gda_meta_struct_free (mstruct);
</para>
- x:
+ fk:
+
+
+<!-- ##### MACRO GDA_META_TABLE_FOREIGN_KEY_ON_UPDATE_POLICY ##### -->
+<para>
+
+</para>
+
+ fk:
+
+
+<!-- ##### MACRO GDA_META_TABLE_FOREIGN_KEY_ON_DELETE_POLICY ##### -->
+<para>
+
+</para>
+
+ fk:
+
+
+<!-- ##### MACRO GDA_META_TABLE_FOREIGN_KEY_IN_SCHEMA ##### -->
+<para>
+
+</para>
+
+ fk:
<!-- ##### MACRO GDA_META_STRUCT_ERROR ##### -->
diff --git a/libgda/gda-meta-struct.c b/libgda/gda-meta-struct.c
index 8587c38..1c50574 100644
--- a/libgda/gda-meta-struct.c
+++ b/libgda/gda-meta-struct.c
@@ -1,6 +1,6 @@
/* gda-meta-struct.c
*
- * Copyright (C) 2008 - 2010 Vivien Malerba
+ * Copyright (C) 2008 - 2011 Vivien Malerba
*
* This Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
@@ -70,6 +70,9 @@ static void gda_meta_table_foreign_key_free (GdaMetaTableForeignKey *tfk);
static GObjectClass *parent_class = NULL;
static GdaAttributesManager *att_mgr;
+#define ON_UPDATE_POLICY "upd_policy";
+#define ON_DELETE_POLICY "del_policy";
+
/* properties */
enum {
PROP_0,
@@ -551,6 +554,30 @@ gda_meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
return dbo;
}
+static GdaMetaForeignKeyPolicy
+policy_string_to_value (const gchar *string)
+{
+ if (!string)
+ return GDA_META_FOREIGN_KEY_UNKNOWN;
+ if (*string == 'C')
+ return GDA_META_FOREIGN_KEY_CASCADE;
+ else if (*string == 'R')
+ return GDA_META_FOREIGN_KEY_RESTRICT;
+ else if (*string == 'N') {
+ if (!strcmp (string + 1, "ONE"))
+ return GDA_META_FOREIGN_KEY_NONE;
+ else
+ return GDA_META_FOREIGN_KEY_NO_ACTION;
+ }
+ else if (*string == 'S') {
+ if (!strcmp (string + 1, "ET NULL"))
+ return GDA_META_FOREIGN_KEY_SET_NULL;
+ else
+ return GDA_META_FOREIGN_KEY_SET_DEFAULT;
+ }
+ return GDA_META_FOREIGN_KEY_UNKNOWN;
+}
+
static GdaMetaDbObject *
_meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
const GValue *icatalog, const GValue *ischema, const GValue *iname,
@@ -829,7 +856,7 @@ _meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
/* foreign keys */
if (mstruct->priv->features & GDA_META_STRUCT_FEATURE_FOREIGN_KEYS) {
- sql = "SELECT ref_table_catalog, ref_table_schema, ref_table_name, constraint_name, ref_constraint_name FROM _referential_constraints WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
+ sql = "SELECT ref_table_catalog, ref_table_schema, ref_table_name, constraint_name, ref_constraint_name, update_rule, delete_rule FROM _referential_constraints WHERE table_catalog = ##tc::string AND table_schema = ##ts::string AND table_name = ##tname::string";
model = gda_meta_store_extract (mstruct->priv->store, sql, error,
"tc", icatalog,
"ts", ischema,
@@ -841,13 +868,18 @@ _meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
for (i = 0; i < nrows; i++) {
GdaMetaTableForeignKey *tfk;
const GValue *fk_catalog, *fk_schema, *fk_name;
-
+ const GValue *upd_policy, *del_policy;
+
fk_catalog = gda_data_model_get_value_at (model, 0, i, error);
if (!fk_catalog) goto onfkerror;
fk_schema = gda_data_model_get_value_at (model, 1, i, error);
if (!fk_schema) goto onfkerror;
fk_name = gda_data_model_get_value_at (model, 2, i, error);
if (!fk_name) goto onfkerror;
+ upd_policy = gda_data_model_get_value_at (model, 5, i, error);
+ if (!upd_policy) goto onfkerror;
+ del_policy = gda_data_model_get_value_at (model, 6, i, error);
+ if (!del_policy) goto onfkerror;
tfk = g_new0 (GdaMetaTableForeignKey, 1);
tfk->meta_table = dbo;
@@ -870,7 +902,23 @@ _meta_struct_complement (GdaMetaStruct *mstruct, GdaMetaDbObjectType type,
dot->reverse_fk_list = g_slist_prepend (dot->reverse_fk_list, tfk);
}
dbo->depend_list = g_slist_append (dbo->depend_list, tfk->depend_on);
-
+
+ tfk->on_update_policy = g_new (GdaMetaForeignKeyPolicy, 1);
+ if (G_VALUE_TYPE (upd_policy) == G_TYPE_STRING)
+ *tfk->on_update_policy = policy_string_to_value (g_value_get_string (upd_policy));
+ else
+ *tfk->on_update_policy = GDA_META_FOREIGN_KEY_UNKNOWN;
+
+ tfk->on_delete_policy = g_new (GdaMetaForeignKeyPolicy, 1);
+ if (G_VALUE_TYPE (upd_policy) == G_TYPE_STRING)
+ *tfk->on_delete_policy = policy_string_to_value (g_value_get_string (del_policy));
+ else
+ *tfk->on_delete_policy = GDA_META_FOREIGN_KEY_UNKNOWN;
+
+ tfk->defined_in_schema = g_new (gboolean, 1);
+ *tfk->defined_in_schema = TRUE;
+
+
/* FIXME: compute @cols_nb, and all the @*_array members (ref_pk_cols_array must be
* initialized with -1 values everywhere */
sql = "SELECT k.column_name, c.ordinal_position FROM _key_column_usage k INNER JOIN _columns c ON (c.table_catalog = k.table_catalog AND c.table_schema = k.table_schema AND c.table_name=k.table_name AND c.column_name=k.column_name) WHERE k.table_catalog = ##tc::string AND k.table_schema = ##ts::string AND k.table_name = ##tname::string AND k.constraint_name = ##cname::string ORDER BY k.ordinal_position";
@@ -1843,6 +1891,9 @@ gda_meta_table_foreign_key_free (GdaMetaTableForeignKey *tfk)
g_free (tfk->fk_names_array);
g_free (tfk->ref_pk_cols_array);
g_free (tfk->ref_pk_names_array);
+ g_free (tfk->on_update_policy);
+ g_free (tfk->on_delete_policy);
+ g_free (tfk->defined_in_schema);
g_free (tfk);
}
diff --git a/libgda/gda-meta-struct.h b/libgda/gda-meta-struct.h
index a1614bf..21f0dfa 100644
--- a/libgda/gda-meta-struct.h
+++ b/libgda/gda-meta-struct.h
@@ -1,6 +1,6 @@
/* gda-meta-struct.h
*
- * Copyright (C) 2008 - 2009 Vivien Malerba
+ * Copyright (C) 2008 - 2011 Vivien Malerba
*
* This Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
@@ -57,6 +57,7 @@ struct _GdaMetaStructClass
{
GObjectClass parent_class;
+ /*< private >*/
/* Padding for future expansion */
void (*_gda_reserved1) (void);
void (*_gda_reserved2) (void);
@@ -64,8 +65,13 @@ struct _GdaMetaStructClass
void (*_gda_reserved4) (void);
};
-/*
- * Type of database object which can be handled
+/**
+ * GdaMetaDbObjectType:
+ * @GDA_META_DB_UNKNOWN: unknown type
+ * @GDA_META_DB_TABLE: represents a table
+ * @GDA_META_DB_VIEW: represents a view
+ *
+ * Type of database object which can be handled as a #GdaMetaDbObject
*/
typedef enum {
GDA_META_DB_UNKNOWN,
@@ -85,7 +91,11 @@ typedef enum {
GDA_META_STRUCT_FEATURE_VIEW_DEPENDENCIES
} GdaMetaStructFeature;
-/*
+/**
+ * GdaMetaSortType:
+ * @GDA_META_SORT_ALHAPETICAL: sort alphabetically
+ * @GDA_META_SORT_DEPENDENCIES: sort by dependencies
+ *
* Types of sorting
*/
typedef enum {
@@ -193,8 +203,35 @@ typedef struct {
gpointer _gda_reserved3;
gpointer _gda_reserved4;
} GdaMetaDbObject;
-#define GDA_META_DB_OBJECT(x) ((GdaMetaDbObject*)(x))
+
+/**
+ * GDA_META_DB_OBJECT:
+ * @dbo: a pointer
+ *
+ * Casts @dbo to a #GdaMetaDbObject, no check is made on the validity of @dbo
+ *
+ * Returns: a pointer to a #GdaMetaDbObject
+ */
+#define GDA_META_DB_OBJECT(dbo) ((GdaMetaDbObject*)(dbo))
+
+/**
+ * GDA_META_TABLE:
+ * @dbo: a pointer
+ *
+ * Casts @dbo to a #GdaMetaTable, no check is made on the validity of @dbo
+ *
+ * Returns: a pointer to a #GdaMetaTable
+ */
#define GDA_META_TABLE(dbobj) (&((dbobj)->extra.meta_table))
+
+/**
+ * GDA_META_VIEW:
+ * @dbo: a pointer
+ *
+ * Casts @dbo to a #GdaMetaView, no check is made on the validity of @dbo
+ *
+ * Returns: a pointer to a #GdaMetaView
+ */
#define GDA_META_VIEW(dbobj) (&((dbobj)->extra.meta_view))
/**
@@ -224,7 +261,17 @@ typedef struct {
gpointer _gda_reserved3;
gpointer _gda_reserved4;
} GdaMetaTableColumn;
-#define GDA_META_TABLE_COLUMN(x) ((GdaMetaTableColumn*)(x))
+
+/**
+ * GDA_META_TABLE_COLUMN:
+ * @col: a pointer
+ *
+ * Casts @col to a #GdaMetaTableColumn, no check is made
+ *
+ * Returns: @col, casted to a #GdaMetaTableColumn
+ */
+#define GDA_META_TABLE_COLUMN(col) ((GdaMetaTableColumn*)(col))
+
const GValue *gda_meta_table_column_get_attribute (GdaMetaTableColumn *tcol, const gchar *attribute);
void gda_meta_table_column_set_attribute (GdaMetaTableColumn *tcol, const gchar *attribute, const GValue *value,
GDestroyNotify destroy);
@@ -241,6 +288,29 @@ void gda_meta_table_column_set_attribute (GdaMetaTableColumn *tcol, con
void gda_meta_table_column_foreach_attribute (GdaMetaTableColumn *tcol, GdaAttributesManagerFunc func, gpointer data);
/**
+ * GdaMetaForeignKeyPolicy:
+ * @GDA_META_FOREIGN_KEY_UNKNOWN: unspecified policy
+ * @GDA_META_FOREIGN_KEY_NONE: not enforced policy
+ * @GDA_META_FOREIGN_KEY_NO_ACTION: return an error, no action taken
+ * @GDA_META_FOREIGN_KEY_RESTRICT: same as @GDA_META_FOREIGN_KEY_NO_ACTION, not deferrable
+ * @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
+ * @GDA_META_FOREIGN_KEY_SET_NULL: policy is to set the referencing column to NULL
+ * @GDA_META_FOREIGN_KEY_SET_DEFAULT: policy is to set the referencing column to its default value
+ *
+ * Defines the filtering policy of a foreign key when invoked on an UPDATE
+ * or DELETE operation.
+ */
+typedef enum {
+ GDA_META_FOREIGN_KEY_UNKNOWN,
+ GDA_META_FOREIGN_KEY_NONE,
+ GDA_META_FOREIGN_KEY_NO_ACTION,
+ GDA_META_FOREIGN_KEY_RESTRICT,
+ GDA_META_FOREIGN_KEY_CASCADE,
+ GDA_META_FOREIGN_KEY_SET_NULL,
+ GDA_META_FOREIGN_KEY_SET_DEFAULT
+} GdaMetaForeignKeyPolicy;
+
+/**
* GdaMetaTableForeignKey:
* @meta_table: the #GdaMetaDbObject for which this structure represents a foreign key
* @depend_on: the #GdaMetaDbObject which is referenced by the foreign key
@@ -266,14 +336,53 @@ typedef struct {
gchar **ref_pk_names_array; /* Ref PK fields names */
/*< private >*/
+ GdaMetaForeignKeyPolicy *on_update_policy;
+ GdaMetaForeignKeyPolicy *on_delete_policy;
+ gboolean *defined_in_schema;
+
/* Padding for future expansion */
gpointer _gda_reserved1;
- gpointer _gda_reserved2;
- gpointer _gda_reserved3;
- gpointer _gda_reserved4;
} GdaMetaTableForeignKey;
-#define GDA_META_TABLE_FOREIGN_KEY(x) ((GdaMetaTableForeignKey*)(x))
+/**
+ * GDA_META_TABLE_FOREIGN_KEY
+ * @fk: a pointer
+ *
+ * Casts @fk to a #GdaMetaTableForeignKey (no check is actuelly being done on @fk's validity)
+ *
+ * Returns: @col, casted to a #GdaMetaTableForeignKey
+ */
+#define GDA_META_TABLE_FOREIGN_KEY(fk) ((GdaMetaTableForeignKey*)(fk))
+/**
+ * GDA_META_TABLE_FOREIGN_KEY_ON_UPDATE_POLICY:
+ * @fk: a pointer to a #GdaMetaTableForeignKey
+ *
+ * Tells the actual policy implemented by @fk when used in the context of an UPDATE.
+ *
+ * Returns: the policy as a #GdaMetaForeignKeyPolicy
+ */
+#define GDA_META_TABLE_FOREIGN_KEY_ON_UPDATE_POLICY(fk) (*(((GdaMetaTableForeignKey*)(fk))->on_update_policy))
+
+/**
+ * GDA_META_TABLE_FOREIGN_KEY_ON_DELETE_POLICY:
+ * @fk: a pointer to a #GdaMetaTableForeignKey
+ *
+ * Tells the actual policy implemented by @fk when used in the context of a DELETE.
+ *
+ * Returns: the policy as a #GdaMetaForeignKeyPolicy
+ */
+#define GDA_META_TABLE_FOREIGN_KEY_ON_DELETE_POLICY(fk) (*(((GdaMetaTableForeignKey*)(fk))->on_update_policy))
+
+/**
+ * GDA_META_TABLE_FOREIGN_KEY_IN_SCHEMA
+ * @fk: a pointer to a #GdaMetaTableForeignKey
+ *
+ * Tells if @fk is an actual foreign key defined in the database's schema, or if it is an indication which
+ * has been added to help Libgda understand the database schema.
+ *
+ * Returns: %TRUE if @fk is an actual foreign key defined in the database's schema
+ */
+#define GDA_META_TABLE_FOREIGN_KEY_IN_SCHEMA(fk) (*(((GdaMetaTableForeignKey*)(fk))->defined_in_schema))
GType gda_meta_struct_get_type (void) G_GNUC_CONST;
GdaMetaStruct *gda_meta_struct_new (GdaMetaStore *store, GdaMetaStructFeature features);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]