[libgda] Sealing GdaMetaStoreChange



commit 5b16d904efce494d8ca0f429e57eedf7318cf17c
Author: Daniel Espinosa <esodan gmail com>
Date:   Thu Apr 21 14:16:43 2016 -0500

    Sealing GdaMetaStoreChange
    
    * This changes actually fails with segmentation fault at tests

 libgda/gda-meta-store.c                     |  190 ++++++++++++++++++++++++---
 libgda/gda-meta-store.h                     |   27 +++--
 libgda/gda-value.c                          |    4 +-
 libgda/gda-value.h                          |   14 +-
 libgda/sqlite/virtual/gda-vconnection-hub.c |   22 ++--
 tests/meta-store/common.c                   |   36 ++----
 6 files changed, 220 insertions(+), 73 deletions(-)
---
diff --git a/libgda/gda-meta-store.c b/libgda/gda-meta-store.c
index bcf3c3a..eff1880 100644
--- a/libgda/gda-meta-store.c
+++ b/libgda/gda-meta-store.c
@@ -68,6 +68,179 @@
 #include "gda-data-meta-wrapper.h"
 #include <libgda/gda-debug-macros.h>
 
+// This is a copy of the macro located at gda-value.h
+#define l_g_value_unset(val) G_STMT_START{ if (G_IS_VALUE (val)) g_value_unset (val); }G_STMT_END
+
+// GdaMetaStoreChange
+
+typedef struct _GdaMetaStoreChange {
+       /* change general information */
+       GdaMetaStoreChangeType  c_type;
+       gchar                  *table_name;
+       GHashTable             *keys; /* key = ('+' or '-') and a column position in @table (string) starting 
at 0, 
+                                      * value = a GValue pointer */
+};
+
+GType
+gda_meta_store_change_get_type (void)
+{
+       static GType type = 0;
+
+       if (G_UNLIKELY (type == 0)) {
+               static GMutex registering;
+               g_mutex_lock (&registering);
+                if (type == 0)
+                       type = g_boxed_type_register_static ("GdaMetaStoreChange",
+                                                            (GBoxedCopyFunc) gda_meta_store_change_copy,
+                                                            (GBoxedFreeFunc) gda_meta_store_change_free);
+               g_mutex_unlock (&registering);
+       }
+
+       return type;
+}
+/**
+ * gda_meta_store_change_new:
+ *
+ * Creates a new #GdaMetaStoreChange
+ */
+GdaMetaStoreChange*
+gda_meta_store_change_new (void)
+{
+  GdaMetaStoreChange* change = g_new0 (GdaMetaStoreChange, 1);
+  change->table_name = NULL;
+  change->c_type = GDA_META_STORE_MODIFY;
+  change->keys = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                                     g_free, (GDestroyNotify) 
gda_value_free);
+}
+
+void
+gda_meta_store_change_set_change_type (GdaMetaStoreChange *change, GdaMetaStoreChangeType ctype)
+{
+  g_return_if_fail (change != NULL);
+  change->c_type = ctype;
+}
+
+GdaMetaStoreChangeType
+gda_meta_store_change_get_change_type (GdaMetaStoreChange *change)
+{
+  g_return_val_if_fail (change != NULL, GDA_META_STORE_MODIFY);
+  return change->c_type;
+}
+/**
+ * gda_meta_store_change_set_table_name:
+ * @change: a #GdaMetaStoreChange
+ * @table_name: name of the table
+ *
+ */
+void
+gda_meta_store_change_set_table_name (GdaMetaStoreChange *change, const gchar *table_name)
+{
+  g_return_if_fail (change != NULL);
+  change->table_name = g_strdup (table_name);
+}
+/**
+ * gda_meta_store_change_get_table_name:
+ * @change: a #GdaMetaStoreChange
+ *
+ * Returns: (transfer full): a string with the table name
+ */
+gchar*
+gda_meta_store_change_get_table_name (GdaMetaStoreChange *change)
+{
+  g_return_val_if_fail (change != NULL, NULL);
+  return g_strdup (change->table_name);
+}
+/**
+ * gda_meta_store_change_get_table_name:
+ * @change: a #GdaMetaStoreChange
+ *
+ * Returns: (element-type utf8 GValue) (transfer none): hash table with string key key = ('+' or '-') and a 
column position in @table (string) starting at 0 and value as #GValue pointer
+ */
+GHashTable*
+gda_meta_store_change_get_keys (GdaMetaStoreChange *change)
+{
+  g_return_val_if_fail (change != NULL, NULL);
+  return change->keys;
+}
+
+/**
+ * gda_meta_store_change_copy:
+ * @src: a #GdaMetaStoreChange
+ *
+ * Returns: a new #GdaMetaStoreChange
+ */
+GdaMetaStoreChange*
+gda_meta_store_change_copy (GdaMetaStoreChange *src)
+{
+  GdaMetaStoreChange* copy;
+  g_return_val_if_fail (src != NULL, NULL);
+  copy = gda_meta_store_change_new ();
+  gda_meta_store_change_set_change_type (copy, gda_meta_store_change_get_change_type (src));
+  gda_meta_store_change_set_table_name (copy, gda_meta_store_change_get_table_name (src));
+  GList *keys = g_hash_table_get_keys (src->keys);
+  while (keys) {
+    g_hash_table_insert (copy->keys, keys->data, g_hash_table_lookup (src->keys, keys->data));
+    keys = keys->next;
+  }
+}
+
+/**
+ * gda_meta_store_change_free:
+ * @src: a #GdaMetaStoreChange to be freed
+ *
+ */
+void
+gda_meta_store_change_free (GdaMetaStoreChange *change)
+{
+  g_return_if_fail (change != NULL);
+  if (change->table_name != NULL)
+    g_free (change->table_name);
+  g_hash_table_unref (change->keys);
+}
+
+/**
+ * gda_value_set_meta_store_change:
+ * @value: a #GValue to set value to
+ * @src: a #GdaMetaStoreChange to be set
+ *
+ */
+void
+gda_value_set_meta_store_change (GValue *value, GdaMetaStoreChange *change)
+{
+  g_return_if_fail (value != NULL);
+  g_return_if_fail (change != NULL);
+
+       l_g_value_unset (value);
+       g_value_init (value, GDA_TYPE_META_STORE_CHANGE);
+       if (change)
+               g_value_set_boxed (value, change);
+       else {
+               g_value_set_boxed (value, gda_meta_store_change_new ());
+       }
+}
+
+/**
+ * gda_value_get_meta_store_change:
+ * @value: a #GValue to get value from
+ * 
+ * Returns: (transfer none): a #GdaMetaStoreChange
+ *
+ */
+GdaMetaStoreChange*
+gda_value_get_meta_store_change (GValue *value)
+{
+  GdaMetaStoreChange *val;
+
+       g_return_val_if_fail (value, NULL);
+       g_return_val_if_fail (gda_value_isa (value, GDA_TYPE_META_STORE_CHANGE), NULL);
+
+       val = (GdaMetaStoreChange*) g_value_get_boxed (value);
+
+       return val;
+}
+
+
+
 /*
    Register GdaMetaContext type
 */
@@ -302,8 +475,6 @@ static void gda_meta_store_get_property (GObject *object,
                                         GParamSpec *pspec);
 
 static gboolean initialize_cnc_struct (GdaMetaStore *store, GError **error);
-static void gda_meta_store_change_free (GdaMetaStoreChange *change);
-
 static GRecMutex init_rmutex;
 #define MUTEX_LOCK() g_rec_mutex_lock(&init_rmutex)
 #define MUTEX_UNLOCK() g_rec_mutex_unlock(&init_rmutex)
@@ -3782,21 +3953,6 @@ _gda_meta_store_finish_data_reset (GdaMetaStore *store, GError **error)
 
 
 
-/*
- * gda_meta_store_change_free
- * @change: a #GdaMetaStoreChange structure
- *
- * Free the memory associated to @change
- */
-static void
-gda_meta_store_change_free (GdaMetaStoreChange *change) {
-       if (!change) return;
-
-       g_free (change->table_name);
-       g_hash_table_destroy (change->keys);
-       g_free (change);
-}
-
 /**
  * gda_meta_store_create_modify_data_model:
  * @store: a #GdaMetaStore object
diff --git a/libgda/gda-meta-store.h b/libgda/gda-meta-store.h
index 8e17845..9250a33 100644
--- a/libgda/gda-meta-store.h
+++ b/libgda/gda-meta-store.h
@@ -64,18 +64,23 @@ typedef enum {
 } GdaMetaStoreChangeType;
 
 /**
- * GdaMetaStoreChange:
- * @c_type:
- * @table_name:
- * @keys: (element-type utf8 GObject.Value):
+ * GdaMetaStoreChange: (ref-func gda_meta_store_change_new) (unref-func gda_meta_store_change_free) 
(get-value-func gda_value_get_meta_store_change) (set-value-func gda_value_set_meta_store_change)
  */
-typedef struct {
-       /* change general information */
-       GdaMetaStoreChangeType  c_type;
-       gchar                  *table_name;
-       GHashTable             *keys; /* key = ('+' or '-') and a column position in @table (string) starting 
at 0, 
-                                      * value = a GValue pointer */
-} GdaMetaStoreChange;
+typedef struct _GdaMetaStoreChange GdaMetaStoreChange;
+
+#define GDA_TYPE_META_STORE_CHANGE (gda_meta_store_change_get_type ())
+
+GType                   gda_meta_store_change_get_type (void) G_GNUC_CONST;
+GdaMetaStoreChange*     gda_meta_store_change_new (void);
+void                    gda_meta_store_change_set_change_type (GdaMetaStoreChange *change, 
GdaMetaStoreChangeType ctype);
+GdaMetaStoreChangeType  gda_meta_store_change_get_change_type (GdaMetaStoreChange *change);
+void                    gda_meta_store_change_set_table_name (GdaMetaStoreChange *change, const gchar 
*table_name);
+gchar*                  gda_meta_store_change_get_table_name (GdaMetaStoreChange *change);
+GHashTable*              gda_meta_store_change_get_keys (GdaMetaStoreChange *change);
+GdaMetaStoreChange*     gda_meta_store_change_copy (GdaMetaStoreChange *src);
+void                    gda_meta_store_change_free (GdaMetaStoreChange *change);
+void                    gda_value_set_meta_store_change (GValue *value, GdaMetaStoreChange *change);
+GdaMetaStoreChange*     gda_value_get_meta_store_change (GValue *value);
 
 
 /* Pointer type for GdaMetaContext */
diff --git a/libgda/gda-value.c b/libgda/gda-value.c
index 532c19b..44d34da 100644
--- a/libgda/gda-value.c
+++ b/libgda/gda-value.c
@@ -585,7 +585,6 @@ gda_binary_get_size (GdaBinary *binary)
 
  * Returns: (transfer full): a newly allocated #GdaBinary which contains a copy of information in @boxed.
  *
- * Free-function: gda_binary_free
  */
 GdaBinary*
 gda_binary_copy (GdaBinary *src)
@@ -2171,8 +2170,7 @@ gda_value_set_binary (GValue *value, const GdaBinary *binary)
        if (binary)
                g_value_set_boxed (value, binary);
        else {
-               GdaBinary bin = {NULL, 0};
-               g_value_set_boxed (value, &bin);
+               g_value_set_boxed (value, gda_binary_new ());
        }
 }
 
diff --git a/libgda/gda-value.h b/libgda/gda-value.h
index b915d2d..cf074df 100644
--- a/libgda/gda-value.h
+++ b/libgda/gda-value.h
@@ -43,10 +43,8 @@ G_BEGIN_DECLS
 /* Definition of the GType's values used in GValue*/
 #define GDA_TYPE_NULL (gda_null_get_type())
 #define GDA_TYPE_DEFAULT (gda_default_get_type())
-#define        GDA_TYPE_BINARY (gda_binary_get_type())
 #define GDA_TYPE_BLOB (gda_blob_get_type())
 #define        GDA_TYPE_GEOMETRIC_POINT (gda_geometricpoint_get_type())
-#define        GDA_TYPE_NUMERIC (gda_numeric_get_type())
 #define        GDA_TYPE_SHORT (gda_short_get_type()) 
 #define        GDA_TYPE_USHORT (gda_ushort_get_type())
 #define GDA_TYPE_TIME (gda_time_get_type())
@@ -56,10 +54,8 @@ G_BEGIN_DECLS
 /* Definition of the GDA_VALUE_HOLDS macros */
 #define GDA_VALUE_HOLDS_NULL(value)            G_VALUE_HOLDS(value, GDA_TYPE_NULL)
 #define GDA_VALUE_HOLDS_DEFAULT(value)         G_VALUE_HOLDS(value, GDA_TYPE_DEFAULT)
-#define GDA_VALUE_HOLDS_BINARY(value)          G_VALUE_HOLDS(value, GDA_TYPE_BINARY)
 #define GDA_VALUE_HOLDS_BLOB(value)            G_VALUE_HOLDS(value, GDA_TYPE_BLOB)
 #define GDA_VALUE_HOLDS_GEOMETRIC_POINT(value) G_VALUE_HOLDS(value, GDA_TYPE_GEOMETRIC_POINT)
-#define GDA_VALUE_HOLDS_NUMERIC(value)         G_VALUE_HOLDS(value, GDA_TYPE_NUMERIC)
 #define GDA_VALUE_HOLDS_SHORT(value)           G_VALUE_HOLDS(value, GDA_TYPE_SHORT)
 #define GDA_VALUE_HOLDS_USHORT(value)          G_VALUE_HOLDS(value, GDA_TYPE_USHORT)
 #define GDA_VALUE_HOLDS_TIME(value)            G_VALUE_HOLDS(value, GDA_TYPE_TIME)
@@ -78,6 +74,9 @@ typedef struct {
 /* GdaNumeric */
 typedef struct _GdaNumeric GdaNumeric;
 
+#define        GDA_TYPE_NUMERIC (gda_numeric_get_type())
+#define GDA_VALUE_HOLDS_NUMERIC(value)         G_VALUE_HOLDS(value, GDA_TYPE_NUMERIC)
+
 GType                             gda_numeric_get_type (void) G_GNUC_CONST;
 GdaNumeric*                       gda_numeric_new (void);
 GdaNumeric*                       gda_numeric_copy (GdaNumeric *src);
@@ -134,12 +133,13 @@ typedef struct {
 } GdaTimestamp;
 
 /**
- * GdaBinary:
- * @data: (array length=binary_length): the actual data as an array
- * @binary_length: length of @data
+ * GdaBinary: (ref-func gda_binary_new) (unref-func gda_binary_free) (get-value-func gda_value_get_binary) 
(set-value-func gda_value_set_binary)
  */
 typedef struct _GdaBinary GdaBinary;
 
+#define GDA_TYPE_BINARY (gda_binary_get_type ())
+#define GDA_VALUE_HOLDS_BINARY(value)          G_VALUE_HOLDS(value, GDA_TYPE_BINARY)
+
 GValue*                           gda_value_new_binary (const guchar *val, glong size);
 const GdaBinary*                                                                       gda_value_get_binary 
(const GValue *value);
 void                              gda_value_set_binary (GValue *value, const GdaBinary *binary);
diff --git a/libgda/sqlite/virtual/gda-vconnection-hub.c b/libgda/sqlite/virtual/gda-vconnection-hub.c
index ae0a833..7f26280 100644
--- a/libgda/sqlite/virtual/gda-vconnection-hub.c
+++ b/libgda/sqlite/virtual/gda-vconnection-hub.c
@@ -884,39 +884,39 @@ meta_changed_cb (G_GNUC_UNUSED GdaMetaStore *store, GSList *changes, HubConnecti
                GValue *tsn, *tn;
 
                /* we are only interested in changes occurring in the "_tables" table */
-               if (!strcmp (ch->table_name, "_tables")) {
-                       switch (ch->c_type) {
+               if (!strcmp (gda_meta_store_change_get_table_name (ch), "_tables")) {
+                       switch (gda_meta_store_change_get_change_type (ch)) {
                        case GDA_META_STORE_ADD: {
                                /* we only want tables where table_short_name = table_name */
-                               tsn = g_hash_table_lookup (ch->keys, "+6");
-                               tn = g_hash_table_lookup (ch->keys, "+2");
+                               tsn = g_hash_table_lookup (gda_meta_store_change_get_keys (ch), "+6");
+                               tn = g_hash_table_lookup (gda_meta_store_change_get_keys (ch), "+2");
                                if (tn && tsn && !gda_value_compare (tsn, tn))
                                        table_add (hc, tn, NULL);
                                break;
                        }
                        case GDA_META_STORE_REMOVE: {
                                /* we only want tables where table_short_name = table_name */
-                               tsn = g_hash_table_lookup (ch->keys, "-6");
-                               tn = g_hash_table_lookup (ch->keys, "-2");
+                               tsn = g_hash_table_lookup (gda_meta_store_change_get_keys (ch), "-6");
+                               tn = g_hash_table_lookup (gda_meta_store_change_get_keys (ch), "-2");
                                if (tn && tsn && !gda_value_compare (tsn, tn))
                                        table_remove (hc, tn);
                                break;
                        }
                        case GDA_META_STORE_MODIFY: {
                                /* we only want tables where table_short_name = table_name */
-                               tsn = g_hash_table_lookup (ch->keys, "-6");
-                               tn = g_hash_table_lookup (ch->keys, "-2");
+                               tsn = g_hash_table_lookup (gda_meta_store_change_get_keys (ch), "-6");
+                               tn = g_hash_table_lookup (gda_meta_store_change_get_keys (ch), "-2");
                                if (tn && tsn && !gda_value_compare (tsn, tn))
                                        table_remove (hc, tn);
-                               tsn = g_hash_table_lookup (ch->keys, "+6");
-                               tn = g_hash_table_lookup (ch->keys, "+2");
+                               tsn = g_hash_table_lookup (gda_meta_store_change_get_keys (ch), "+6");
+                               tn = g_hash_table_lookup (gda_meta_store_change_get_keys (ch), "+2");
                                if (tn && tsn && !gda_value_compare (tsn, tn))
                                        table_add (hc, tn, NULL);
                                break;
                        }
                        }
                }
-               else if (!strcmp (ch->table_name, "_columns")) {
+               else if (!strcmp (gda_meta_store_change_get_table_name (ch), "_columns")) {
                        /* TODO */
                }
        }
diff --git a/tests/meta-store/common.c b/tests/meta-store/common.c
index 503c89a..5ce5bf1 100644
--- a/tests/meta-store/common.c
+++ b/tests/meta-store/common.c
@@ -20,16 +20,6 @@
 #include "common.h"
 #include <sql-parser/gda-sql-parser.h>
 
-/* copied from gda-meta-store.c */
-static void
-gda_meta_store_change_free (GdaMetaStoreChange *change) {
-       if (!change) return;
-       
-       g_free (change->table_name);
-       g_hash_table_destroy (change->keys);
-       g_free (change);
-}
-
 /* list of changes expected during a modify operation */
 GSList *expected_changes;
 
@@ -74,15 +64,15 @@ stringify_a_change (GdaMetaStoreChange *ac)
        gchar *str;
        GString *string;
 
-       string = g_string_new (ac->table_name);
-       if (ac->c_type == GDA_META_STORE_ADD)
+       string = g_string_new (gda_meta_store_change_get_table_name (ac));
+       if (gda_meta_store_change_get_change_type (ac) == GDA_META_STORE_ADD)
                g_string_append (string, " (ADD)");
-       else if (ac->c_type == GDA_META_STORE_MODIFY)
+       else if (gda_meta_store_change_get_change_type (ac) == GDA_META_STORE_MODIFY)
                g_string_append (string, " (MOD)");
        else
                g_string_append (string, " (DEL)");
        g_string_append_c (string, '\n');
-       g_hash_table_foreach (ac->keys, (GHFunc) change_key_func, &hlist);
+       g_hash_table_foreach (gda_meta_store_change_get_keys (ac), (GHFunc) change_key_func, &hlist);
        
        GSList *list;
        for (list = hlist; list; list = list->next) {
@@ -241,10 +231,9 @@ common_declare_expected_change (const gchar *table_name, GdaMetaStoreChangeType
        }
        else {
                GdaMetaStoreChange *ac;
-               ac = g_new0 (GdaMetaStoreChange, 1);
-               ac->c_type = type;
-               ac->table_name = g_strdup (table_name);
-               ac->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) 
gda_value_free);
+               ac = gda_meta_store_change_new ();
+               gda_meta_store_change_set_change_type (ac, type);
+               gda_meta_store_change_set_table_name (ac, table_name);
 
                /* use args */
                va_list args;
@@ -253,7 +242,7 @@ common_declare_expected_change (const gchar *table_name, GdaMetaStoreChangeType
                for (pname = va_arg (args, gchar*); pname; pname = va_arg (args, gchar*)) {
                        GValue *v;
                        g_value_set_string ((v = gda_value_new (G_TYPE_STRING)), va_arg (args, gchar*));
-                       g_hash_table_insert (ac->keys, g_strdup (pname), v);
+                       g_hash_table_insert (gda_meta_store_change_get_keys (ac), g_strdup (pname), v);
                }
                va_end (args);
 
@@ -272,10 +261,9 @@ common_declare_expected_insertions_from_model (const gchar *table_name, GdaDataM
        nrows = gda_data_model_get_n_rows (model);
        for (i = 0; i < nrows; i++) {
                GdaMetaStoreChange *ac;
-               ac = g_new0 (GdaMetaStoreChange, 1);
-               ac->c_type = GDA_META_STORE_ADD;
-               ac->table_name = g_strdup (table_name);
-               ac->keys = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) 
gda_value_free);
+               ac = gda_meta_store_change_new ();
+               gda_meta_store_change_set_change_type (ac, GDA_META_STORE_ADD);
+               gda_meta_store_change_set_table_name (ac, table_name);
 
                for (j = 0; j < ncols; j++) {
                        gchar *str;
@@ -288,7 +276,7 @@ common_declare_expected_insertions_from_model (const gchar *table_name, GdaDataM
                                         lerror && lerror->message ? lerror->message : "No detail");
                                exit (1);
                        }
-                       g_hash_table_insert (ac->keys, str, gda_value_copy (value));
+                       g_hash_table_insert (gda_meta_store_change_get_keys (ac), str, gda_value_copy 
(value));
                }
 
                gchar *str;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]