[gom] all: Stop first-time GOM users from having to set the "new in version"



commit 25c5bf0f0554d6b7ec1e3de9c980eab12c619186
Author: Bastien Nocera <hadess hadess net>
Date:   Thu Apr 17 23:19:18 2014 +0200

    all: Stop first-time GOM users from having to set the "new in version"
    
    Applications that use GOM from the get-go shouldn't have to
    call "new in version" for every single one for their initial
    properties/columns.
    
    Nor should applications with existing columns have to set their
    "new in version" to 0 for those columns.
    
    Instead, we'll try to create the table with all the columns
    that are new in version 1 in one go, which can fail gracefully.

 gom/gom-command-builder.c  |   40 +++++++++++++++++++++++++++++-----------
 gom/gom-resource.c         |    4 +++-
 tests/test-gom-stress.c    |    2 --
 tests/test-gom-transform.c |    4 ----
 4 files changed, 32 insertions(+), 18 deletions(-)
---
diff --git a/gom/gom-command-builder.c b/gom/gom-command-builder.c
index e41e939..29fecd2 100644
--- a/gom/gom-command-builder.c
+++ b/gom/gom-command-builder.c
@@ -98,7 +98,10 @@ static gboolean
 is_new_in_version (GParamSpec *pspec,
                    guint       version)
 {
-   return GPOINTER_TO_UINT(g_param_spec_get_qdata(pspec, GOM_RESOURCE_NEW_IN_VERSION)) == version;
+   /* This is a bit ugly, but this allows us to consider
+    * an unset value to be new in version 1. Version 0
+    * is for "pre-GOM" SQLite usage. */
+   return GPOINTER_TO_INT(g_param_spec_get_qdata(pspec, GOM_RESOURCE_NEW_IN_VERSION) + 1) == version;
 }
 
 static void
@@ -156,8 +159,6 @@ add_pkey_column (GString          *str,
 {
    GParamSpec *primary_pspec;
 
-   g_string_append(str, " (");
-
    primary_pspec = g_object_class_find_property(G_OBJECT_CLASS(klass),
                                                 klass->primary_key);
    g_assert(primary_pspec);
@@ -166,7 +167,6 @@ add_pkey_column (GString          *str,
                           sql_type_for_column (primary_pspec));
    if (is_dynamic_pkey(primary_pspec))
      g_string_append(str, " AUTOINCREMENT");
-   g_string_append(str, ")");
 }
 
 static void
@@ -369,26 +369,42 @@ gom_command_builder_build_create (GomCommandBuilder *builder,
 
    klass = g_type_class_ref(priv->resource_type);
 
-   /* Create the table */
+   primary_pspec = g_object_class_find_property(G_OBJECT_CLASS(klass),
+                                                klass->primary_key);
+   g_assert(primary_pspec);
+
+   pspecs = g_object_class_list_properties(G_OBJECT_CLASS(klass), &n_pspecs);
+
+   /* Create the table if it doesn't already exist*/
    if (version == 1) {
       str = g_string_new("CREATE TABLE IF NOT EXISTS ");
       add_table_name(str, klass);
+      g_string_append(str, "(");
       add_pkey_column(str, klass);
 
+      for (i = 0; i < n_pspecs; i++) {
+         if (pspecs[i] != primary_pspec &&
+             is_mapped(pspecs[i]) &&
+             is_new_in_version(pspecs[i], version)) {
+            g_string_append(str, ",");
+            g_string_append_printf(str, "'%s' %s",
+                                   pspecs[i]->name,
+                                   sql_type_for_column (pspecs[i]));
+            add_reference(str, pspecs[i]);
+         }
+      }
+      g_string_append(str, ")");
       command = g_object_new(GOM_TYPE_COMMAND,
                              "adapter", priv->adapter,
                              "sql", str->str,
                              NULL);
       ret = g_list_prepend(NULL, command);
       g_string_free(str, TRUE);
-   }
 
-   /* And now each of the columns */
-   primary_pspec = g_object_class_find_property(G_OBJECT_CLASS(klass),
-                                                klass->primary_key);
-   g_assert(primary_pspec);
+      goto out;
+   }
 
-   pspecs = g_object_class_list_properties(G_OBJECT_CLASS(klass), &n_pspecs);
+   /* And now each of the columns for versions > 1 */
    for (i = 0; i < n_pspecs; i++) {
      if (pspecs[i] != primary_pspec &&
          is_mapped(pspecs[i]) &&
@@ -409,6 +425,8 @@ gom_command_builder_build_create (GomCommandBuilder *builder,
        g_string_free(str, TRUE);
      }
    }
+
+out:
    g_free(pspecs);
 
    g_type_class_unref(klass);
diff --git a/gom/gom-resource.c b/gom/gom-resource.c
index 232511c..9e62eb3 100644
--- a/gom/gom-resource.c
+++ b/gom/gom-resource.c
@@ -68,7 +68,9 @@ gom_resource_class_set_property_new_in_version (GomResourceClass *resource_class
    pspec = g_object_class_find_property(G_OBJECT_CLASS(resource_class), property_name);
    g_assert(pspec);
 
-   g_param_spec_set_qdata(pspec, GOM_RESOURCE_NEW_IN_VERSION, GUINT_TO_POINTER(version));
+   /* See is_new_in_version() in gom-repository.c for the reasoning
+    * behind the "- 1" */
+   g_param_spec_set_qdata(pspec, GOM_RESOURCE_NEW_IN_VERSION, GINT_TO_POINTER(version - 1));
 }
 
 void
diff --git a/tests/test-gom-stress.c b/tests/test-gom-stress.c
index 2c8f5e6..07dba03 100644
--- a/tests/test-gom-stress.c
+++ b/tests/test-gom-stress.c
@@ -127,7 +127,6 @@ item_resource_class_init (ItemResourceClass *klass)
                                                G_PARAM_READWRITE);
   g_object_class_install_property(object_class, PROP_FIRST_NAME,
                                   specs[PROP_FIRST_NAME]);
-  gom_resource_class_set_property_new_in_version(GOM_RESOURCE_CLASS(object_class), "first-name", 1);
 
   specs[PROP_SURNAME] = g_param_spec_string("surname",
                                             "Surname",
@@ -136,7 +135,6 @@ item_resource_class_init (ItemResourceClass *klass)
                                             G_PARAM_READWRITE);
   g_object_class_install_property(object_class, PROP_SURNAME,
                                   specs[PROP_SURNAME]);
-  gom_resource_class_set_property_new_in_version(GOM_RESOURCE_CLASS(object_class), "surname", 1);
 }
 
 static void
diff --git a/tests/test-gom-transform.c b/tests/test-gom-transform.c
index 0794ad7..e8b9657 100644
--- a/tests/test-gom-transform.c
+++ b/tests/test-gom-transform.c
@@ -186,7 +186,6 @@ item_resource_class_init (ItemResourceClass *klass)
                                             G_PARAM_READWRITE);
   g_object_class_install_property(object_class, PROP_PARENT_ID,
                                   specs[PROP_PARENT_ID]);
-  gom_resource_class_set_property_new_in_version(GOM_RESOURCE_CLASS(object_class), "parent-id", 1);
   gom_resource_class_set_reference(resource_class, "parent-id", "items", "id");
 
   specs[PROP_PIXBUF] = g_param_spec_object("pixbuf",
@@ -198,7 +197,6 @@ item_resource_class_init (ItemResourceClass *klass)
                                   specs[PROP_PIXBUF]);
   gom_resource_class_set_property_transform(resource_class, "pixbuf",
                                             pixbuf_to_bytes, pixbuf_from_bytes);
-  gom_resource_class_set_property_new_in_version(GOM_RESOURCE_CLASS(object_class), "pixbuf", 1);
   specs[PROP_STRV] = g_param_spec_boxed("strv",
                                         "Strv",
                                         "The Strv for the item.",
@@ -206,7 +204,6 @@ item_resource_class_init (ItemResourceClass *klass)
                                         G_PARAM_READWRITE);
   g_object_class_install_property(object_class, PROP_STRV,
                                   specs[PROP_STRV]);
-  gom_resource_class_set_property_new_in_version(GOM_RESOURCE_CLASS(object_class), "strv", 1);
   specs[PROP_DATE_TIME] = g_param_spec_boxed("date_time",
                                              "DateTime",
                                              "The DateTime for the item.",
@@ -214,7 +211,6 @@ item_resource_class_init (ItemResourceClass *klass)
                                              G_PARAM_READWRITE);
   g_object_class_install_property(object_class, PROP_DATE_TIME,
                                   specs[PROP_DATE_TIME]);
-  gom_resource_class_set_property_new_in_version(GOM_RESOURCE_CLASS(object_class), "date_time", 1);
 }
 
 static void


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