GList * midgard_core_qb_set_object_from_query (MidgardQueryBuilder *builder, guint select_type, MidgardObject **nobject) { g_assert(builder != NULL); guint ret_rows, ret_fields; MidgardConnection *mgd = builder->priv->mgd; gchar *sql = midgard_core_qb_get_sql( builder, select_type, midgard_query_builder_get_object_select(builder, select_type)); GSList *olist = NULL; MidgardDBObjectClass *dbklass = MIDGARD_DBOBJECT_CLASS(g_type_class_peek(builder->priv->type)); if (!dbklass) { MIDGARD_ERRNO_SET_STRING (mgd, MGD_ERR_INTERNAL, "Failed to peek MidgardDBObjectClass pointer"); return NULL; } if (dbklass->dbpriv->set_from_sql) { if (select_type != MQB_SELECT_GUID) { olist = dbklass->dbpriv->set_from_sql(mgd, builder->priv->type, ((const gchar *)sql)); g_free(sql); return (GList *)olist; } } GdaDataModel *model = midgard_core_query_get_model(builder->priv->mgd, sql); g_free(sql); if(!model) return NULL; MidgardObject *object = NULL; gint rows, columns; const GValue *gvalue = NULL; ret_rows = gda_data_model_get_n_rows(model); ret_fields = gda_data_model_get_n_columns(model); /* records found , allocate as many objects as many returned rows */ GList *list = NULL; if(ret_rows == 0) { g_object_unref(model); return list; } /* We count rows only */ if(select_type == MQB_SELECT_GUID) { gvalue = midgard_data_model_get_value_at(model, 0, 0); if (!gvalue || !G_IS_VALUE (gvalue)) { g_object_unref (model); return 0; } MidgardTypeHolder *holder = g_new(MidgardTypeHolder, 1); GValue val = {0, }; g_value_init (&val, G_TYPE_INT64); g_value_transform (gvalue, &val); holder->elements = (guint)g_value_get_int64((GValue*)&val); list = g_list_append(list, holder); g_object_unref(model); g_value_unset (&val); return list; } /* Get every row */ for (rows = 0; rows < ret_rows; rows++) { if(!nobject) object = g_object_new (builder->priv->type, "connection", mgd, NULL); else object = *nobject; MGD_OBJECT_IN_STORAGE (object) = TRUE; if(dbklass->dbpriv->__set_from_sql != NULL) { dbklass->dbpriv->__set_from_sql(MIDGARD_DBOBJECT(object), model, rows); } else { /* Compute number of metadata properties */ guint n_md_props = 0; MidgardMetadata *mklass = (MidgardMetadata *)MGD_DBCLASS_METADATA_CLASS (dbklass); if (mklass) n_md_props = g_hash_table_size (MGD_DBCLASS_STORAGE_DATA (mklass)->prophash); guint __cols = n_md_props + 1; /* Add one for guid */ /* we have guid and metadata columns first */ for (columns = __cols; columns < ret_fields; columns++) { gvalue = midgard_data_model_get_value_at(model, columns, rows); const gchar *coltitle = gda_data_model_get_column_title(model, columns); GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(object), coltitle); if(G_IS_VALUE(gvalue)) { if (!pspec) { g_warning("Failed to found (unregistered) %s property (%s class)", coltitle, G_OBJECT_TYPE_NAME(object)); continue; } if (G_VALUE_TYPE (gvalue) == GDA_TYPE_BINARY && G_TYPE_FUNDAMENTAL (pspec->value_type) == G_TYPE_STRING) { gchar *stringified = midgard_core_query_binary_stringify ((GValue *)gvalue); g_object_set (G_OBJECT (object), coltitle, stringified, NULL); g_free (stringified); } else if (pspec->value_type != G_VALUE_TYPE (gvalue)) { GValue _convert = {0, }; g_value_init (&_convert, pspec->value_type); if (g_value_transform (gvalue, &_convert)) { /* FIXME, remove workaround once it's fixed in GDA */ /* https://bugzilla.gnome.org/show_bug.cgi?id=617550 */ guint dbtype = mgd->priv->config->priv->dbtype; if (dbtype == MIDGARD_DB_TYPE_MYSQL && G_VALUE_TYPE (gvalue) == GDA_TYPE_BLOB) { gchar *tmp_str = __default_unescape_string (g_value_get_string (&_convert)); if (tmp_str) g_value_take_string (&_convert, tmp_str); } g_object_set_property (G_OBJECT (object), coltitle, &_convert); } else { g_warning ("Failed to convert %s to %s for %s property", G_VALUE_TYPE_NAME (gvalue), G_VALUE_TYPE_NAME (&_convert), coltitle); } g_value_unset (&_convert); } else { g_object_set_property(G_OBJECT(object), coltitle, gvalue); } } else if (gda_value_is_null(gvalue)) { switch (pspec->value_type) { case G_TYPE_INT: case G_TYPE_UINT: g_object_set(G_OBJECT(object), coltitle, 0, NULL); break; case G_TYPE_STRING: g_object_set(G_OBJECT(object), coltitle, "", NULL); break; default: g_warning("Found (%s) not a value at %d.%d (%s)", g_type_name(pspec->value_type), columns, rows, gda_data_model_get_column_title(model, columns)); break; } } } } /* Set guid */ const gchar *guid; gvalue = midgard_data_model_get_value_at(model, 0, rows); if(G_IS_VALUE(gvalue) && G_VALUE_HOLDS_STRING(gvalue)){ guid = g_value_get_string(gvalue); g_free((gchar *)MIDGARD_DBOBJECT(object)->dbpriv->guid); MIDGARD_DBOBJECT(object)->dbpriv->guid = g_strdup(guid); } /* Set metadata */ MidgardMetadata *metadata = MGD_DBOBJECT_METADATA (object); if (metadata) { GParamSpec *pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(object), "metadata"); if (pspec) __mqb_set_metadata(metadata, model, rows); } list = g_list_append(list, G_OBJECT(object)); } g_object_unref(model); return list; }
void _midgard_dbobject_set_from_data_model (MidgardDBObject *self, GdaDataModel *model, gint row, guint column_id) { g_return_if_fail (self != NULL); g_return_if_fail (model != NULL); g_return_if_fail (row > -1); GError *error = NULL; /* Set user defined properties */ guint n_props; guint i; GParamSpec **pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (self), &n_props); if (!pspecs) return; const GValue *pval; for (i = 1; i < n_props; i++) { const gchar *pname = pspecs[i]->name; if (!(pspecs[i]->flags & G_PARAM_WRITABLE)) { g_debug ("Ignoring read only property %s \n", pname); continue; } gint col_idx = gda_data_model_get_column_index (model, pname); if (col_idx == -1) continue; pval = gda_data_model_get_value_at (model, col_idx, row, &error); if (!pval) { g_warning ("Failed to get '%s' property value: %s", pname, error && error->message ? error->message : "Unknown reason"); continue; } /* Overwrite NULL values */ if (G_VALUE_TYPE (pval) == GDA_TYPE_NULL && pspecs[i]->value_type == G_TYPE_STRING) { g_object_set (G_OBJECT (self), pname, "", NULL); } else if (G_VALUE_TYPE (pval) == GDA_TYPE_BLOB && G_TYPE_FUNDAMENTAL (pspecs[i]->value_type) == G_TYPE_STRING) { gchar *stringified = midgard_core_query_binary_stringify ((GValue*)pval); g_object_set (G_OBJECT (self), pname, stringified, NULL); g_free (stringified); } else { g_object_set_property (G_OBJECT (self), pname, pval); } column_id++; } g_free (pspecs); /* Set metadata */ MidgardDBObject *dbobject = MIDGARD_DBOBJECT (self); MidgardMetadata *metadata = MGD_DBOBJECT_METADATA (dbobject); if (metadata) MIDGARD_DBOBJECT_GET_CLASS (MIDGARD_DBOBJECT (metadata))->dbpriv->set_from_data_model ( MIDGARD_DBOBJECT (metadata), model, row, column_id); return; }