void                 
_propagate_columns (MidgardSqlQueryResult *self, guint *n_objects, GError **error)
{
	/* No model, no columns. Return NULL and set error */
	if (self->model == NULL || self->n_columns == 0) {
		g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_INTERNAL,
				"QueryResult holds empty data model"); 
		return;
	}

	guint i = 0;
	if (self->columns != NULL) {
		*n_objects = self->n_columns;
		return;
	}

	g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_INTERNAL,
			"Columns should be propagated with temporary midgard_sql_query_result_set_columns()");
	return;

	GdaDataModel *model = GDA_DATA_MODEL (self->model);
	self->n_columns = gda_data_model_get_n_columns (model);
	*n_objects = self->n_columns;
	if (self->n_columns == 0)
		return;

	self->columns = g_new (MidgardSqlQueryColumn*, self->n_columns);
	for (i = 0; i < self->n_columns; i++) {	
		MidgardQueryProperty *query_property = 
			midgard_query_property_new (gda_data_model_get_column_title (model, i), NULL);
		self->columns[i] = midgard_sql_query_column_new (query_property, "FIXME", 
			gda_data_model_get_column_name (model, i));
	}

	return;
}
Example #2
0
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;	
}
Example #3
0
/**
 * base_tool_output_data_model_to_string:
 */
gchar *
base_tool_output_data_model_to_string (GdaDataModel *model, ToolOutputFormat format, FILE *stream, GdaSet *options)
{
    if (!GDA_IS_DATA_MODEL (model))
        return NULL;

    if (format & BASE_TOOL_OUTPUT_FORMAT_DEFAULT) {
        gchar *tmp;
        GdaSet *local_options;
        gint width;
        base_tool_input_get_size (&width, NULL);
        local_options = gda_set_new_inline (6, "NAME", G_TYPE_BOOLEAN, TRUE,
                                            "NULL_AS_EMPTY", G_TYPE_BOOLEAN, TRUE,
                                            "MAX_WIDTH", G_TYPE_INT, width,
                                            "COLUMN_SEPARATORS", G_TYPE_BOOLEAN, TRUE,
                                            "SEPARATOR_LINE", G_TYPE_BOOLEAN, TRUE,
                                            "NAMES_ON_FIRST_LINE", G_TYPE_BOOLEAN, TRUE);
        if (options)
            gda_set_merge_with_set (local_options, options);
        tmp = gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_TEXT_TABLE, NULL, 0, NULL, 0,
                                               local_options);
        g_object_unref (local_options);
        if (GDA_IS_DATA_SELECT (model)) {
            gchar *tmp2, *tmp3;
            gdouble etime;
            g_object_get ((GObject*) model, "execution-delay", &etime, NULL);
            tmp2 = g_strdup_printf ("%s: %.03f s", _("Execution delay"), etime);
            tmp3 = g_strdup_printf ("%s\n%s", tmp, tmp2);
            g_free (tmp);
            g_free (tmp2);
            return tmp3;
        }
        else
            return tmp;
    }
    else if (format & BASE_TOOL_OUTPUT_FORMAT_XML)
        return gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_DATA_ARRAY_XML,
                                                NULL, 0,
                                                NULL, 0, NULL);
    else if (format & BASE_TOOL_OUTPUT_FORMAT_CSV) {
        gchar *retval;
        GdaSet *optexp;
        optexp = make_options_set_from_string ("csv", options);
        retval = gda_data_model_export_to_string (model, GDA_DATA_MODEL_IO_TEXT_SEPARATED,
                 NULL, 0,
                 NULL, 0, optexp);
        if (optexp)
            g_object_unref (optexp);
        return retval;
    }
    else if (format & BASE_TOOL_OUTPUT_FORMAT_HTML) {
        xmlBufferPtr buffer;
        xmlNodePtr top, div, table, node, row_node, col_node, header, meta;
        gint ncols, nrows, i, j;
        gchar *str;

        top = xmlNewNode (NULL, BAD_CAST "html");
        header = xmlNewChild (top, NULL, BAD_CAST "head", NULL);
        meta = xmlNewChild (header, NULL, BAD_CAST "meta", NULL);
        xmlSetProp (meta, BAD_CAST "http-equiv", BAD_CAST "content-type");
        xmlSetProp (meta, BAD_CAST "content", BAD_CAST "text/html; charset=UTF-8");
        div = xmlNewChild (top, NULL, BAD_CAST "body", NULL);
        table = xmlNewChild (div, NULL, BAD_CAST "table", NULL);
        xmlSetProp (table, BAD_CAST "border", BAD_CAST "1");

        if (g_object_get_data (G_OBJECT (model), "name"))
            xmlNewTextChild (table, NULL, BAD_CAST "caption", g_object_get_data (G_OBJECT (model), "name"));

        ncols = gda_data_model_get_n_columns (model);
        nrows = gda_data_model_get_n_rows (model);

        row_node = xmlNewChild (table, NULL, BAD_CAST "tr", NULL);
        for (j = 0; j < ncols; j++) {
            const gchar *cstr;
            cstr = gda_data_model_get_column_title (model, j);
            col_node = xmlNewTextChild (row_node, NULL, BAD_CAST "th", BAD_CAST cstr);
            xmlSetProp (col_node, BAD_CAST "align", BAD_CAST "center");
        }

        for (i = 0; i < nrows; i++) {
            row_node = xmlNewChild (table, NULL, BAD_CAST "tr", NULL);
            xmlSetProp (row_node, BAD_CAST "valign", BAD_CAST "top");
            for (j = 0; j < ncols; j++) {
                const GValue *value;
                value = gda_data_model_get_value_at (model, j, i, NULL);
                if (!value) {
                    col_node = xmlNewChild (row_node, NULL, BAD_CAST "td", BAD_CAST "ERROR");
                    xmlSetProp (col_node, BAD_CAST "align", BAD_CAST "left");
                }
                else {
                    str = gda_value_stringify (value);
                    col_node = xmlNewTextChild (row_node, NULL, BAD_CAST "td", BAD_CAST str);
                    xmlSetProp (col_node, BAD_CAST "align", BAD_CAST "left");
                    g_free (str);
                }
            }
        }

        node = xmlNewChild (div, NULL, BAD_CAST "p", NULL);
        str = g_strdup_printf (ngettext ("(%d row)", "(%d rows)", nrows), nrows);
        xmlNodeSetContent (node, BAD_CAST str);
        g_free (str);

        buffer = xmlBufferCreate ();
        xmlNodeDump (buffer, NULL, top, 0, 1);
        str = g_strdup ((gchar *) xmlBufferContent (buffer));
        xmlBufferFree (buffer);
        xmlFreeNode (top);
        return str;
    }
    else
        TO_IMPLEMENT;

    return NULL;
}