gboolean
_midgard_workspace_get_by_path (const MidgardWorkspaceManager *manager, MidgardWorkspaceStorage *wss, const gchar *path, GError **error)
{
	g_return_val_if_fail (wss != NULL, FALSE);
	g_return_val_if_fail (path != NULL, FALSE);	

	MidgardWorkspace *self = MIDGARD_WORKSPACE (wss);
	MidgardConnection *mgd = manager->priv->mgd;
	g_return_val_if_fail (mgd != NULL, FALSE);

	GError *err = NULL;
	gint id = 0;
	guint row_id;
	id = midgard_core_workspace_get_id_by_path (mgd, path, &row_id, &err);

	if (id == -1) {
		g_propagate_error (error, err);
		return FALSE;
	}

	MidgardDBObjectClass *dbklass = MIDGARD_DBOBJECT_GET_CLASS (self);
	dbklass->dbpriv->set_from_data_model (MIDGARD_DBOBJECT (self), mgd->priv->workspace_model, row_id, 0);

	return TRUE;
}
static void __weak_ref_notify (gpointer data, GObject *object)
{
	if (data != NULL && G_IS_OBJECT (data)) {	
		MidgardDBObject *dbobject = MIDGARD_DBOBJECT (data);
		MGD_OBJECT_CNC (dbobject) = NULL;
	}
}
static void
__midgard_dbobject_set_property (GObject *object, guint property_id,
		const GValue *value, GParamSpec *pspec)
{
	GObject *mgd;
	switch (property_id) {

		case PROPERTY_CONNECTION:
			if (!G_VALUE_HOLDS_OBJECT (value)) 
				return;

			mgd = g_value_get_object (value);

			if (!MIDGARD_IS_CONNECTION (mgd))
				return;
	
			MIDGARD_DBOBJECT (object)->dbpriv->mgd = MIDGARD_CONNECTION (mgd);
			/* Add weak reference callback to connection. 
			 * Instead of keeping connection's alive (implicitly) we create sentinel 
			 * which guarantees connection's pointer to be null if connection is destroyed. */
			g_object_weak_ref (mgd, __weak_ref_notify, object);

			break;

  		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
			break;
	}
}
static gboolean 
_midgard_workspace_update (const MidgardWorkspaceManager *manager, MidgardWorkspaceStorage *ws, GError **error)
{
	g_return_val_if_fail (manager != NULL, FALSE);
	g_return_val_if_fail (ws != NULL, FALSE);

	MidgardWorkspace *self = MIDGARD_WORKSPACE (ws);
	MidgardConnection *mgd = manager->priv->mgd;
	MGD_OBJECT_CNC (self) = mgd;
	g_return_val_if_fail (mgd != NULL, FALSE);

	if (self->priv->id == 0) {
		g_set_error (error, MIDGARD_WORKSPACE_STORAGE_ERROR, MIDGARD_WORKSPACE_STORAGE_ERROR_INVALID_VALUE,
					"Invalid value ID for workspace"); 
		return FALSE;
	}

	gchar *workspace_name = self->priv->name;
	if (workspace_name == NULL 
			|| (workspace_name != NULL && *workspace_name == '\0')) {
		g_set_error (error, MIDGARD_WORKSPACE_STORAGE_ERROR, MIDGARD_WORKSPACE_STORAGE_ERROR_INVALID_VALUE,
					"Invalid (empty or null) workspace's name"); 
		return FALSE;
	}

	/* Check duplicate */
	const MidgardWorkspaceContext *context = midgard_workspace_get_context (self);
	if (context) {
		MidgardWorkspace *ws_dup = (MidgardWorkspace *) midgard_workspace_storage_get_workspace_by_name (MIDGARD_WORKSPACE_STORAGE (context), workspace_name);	
		if (ws_dup 
				&& g_str_equal (ws_dup->priv->name, workspace_name)
				&& ws_dup->priv->id != self->priv->id) {
			g_object_unref (ws_dup);
			g_set_error (error, MIDGARD_WORKSPACE_STORAGE_ERROR, MIDGARD_WORKSPACE_STORAGE_ERROR_NAME_EXISTS,
					"Workspace with given '%s' name already exists in this context", workspace_name); 
			return FALSE;
		}

		if (g_str_equal (ws_dup->priv->name, workspace_name)) {
			g_object_unref (ws_dup);
			return TRUE;
		}		

		if (ws_dup)
			g_object_unref (ws_dup);
	}

	if (midgard_core_query_update_dbobject_record (MIDGARD_DBOBJECT (self), NULL)) {
		midgard_core_workspace_list_all (mgd, FALSE);
		return TRUE;
	}

	g_set_error (error, MIDGARD_GENERIC_ERROR, MGD_ERR_INTERNAL, "%s", midgard_connection_get_error_string (mgd));

	return FALSE;
}
static void
__midgard_dbobject_instance_init (GTypeInstance *instance, gpointer g_class)
{
	MidgardDBObject *object = (MidgardDBObject *) instance;

	MIDGARD_DBOBJECT (object)->dbpriv = g_new(MidgardDBObjectPrivate, 1);
	MIDGARD_DBOBJECT (object)->dbpriv->mgd = NULL; /* read only */
	MIDGARD_DBOBJECT (object)->dbpriv->guid = NULL;
	MIDGARD_DBOBJECT (object)->dbpriv->datamodel = NULL;
	MIDGARD_DBOBJECT (object)->dbpriv->row = -1;	
	MIDGARD_DBOBJECT (object)->dbpriv->has_metadata = FALSE;
	MIDGARD_DBOBJECT (object)->dbpriv->metadata = NULL;
	MIDGARD_DBOBJECT (object)->dbpriv->is_in_storage = FALSE;

	MIDGARD_DBOBJECT (object)->dbpriv->storage_data =
		MIDGARD_DBOBJECT_GET_CLASS (object)->dbpriv->storage_data;

}
static void 
midgard_dbobject_dispose (GObject *object)
{
	MidgardDBObject *self = MIDGARD_DBOBJECT (object);
	if (self->dbpriv->datamodel && G_IS_OBJECT (self->dbpriv->datamodel))
		g_object_unref(self->dbpriv->datamodel);

	self->dbpriv->row = -1;

	MidgardMetadata *metadata = MGD_DBOBJECT_METADATA (self);
	if (metadata && G_IS_OBJECT (metadata)) {
		g_object_unref (metadata);
		MGD_DBOBJECT_METADATA (self) = NULL;
	}

	/* Nullify connection's pointer. */
	MidgardConnection *mgd = MIDGARD_DBOBJECT (self)->dbpriv->mgd;
	if (mgd != NULL && G_IS_OBJECT (mgd)) {
		g_object_weak_unref (G_OBJECT(self->dbpriv->mgd), __weak_ref_notify, self);	
		MIDGARD_DBOBJECT (self)->dbpriv->mgd = NULL;
	}

	parent_class->dispose (object);
}
Exemple #7
0
static GList *midgard_query_builder_execute_or_count(MidgardQueryBuilder *builder, MidgardTypeHolder *holder, guint select_type)
{
	g_assert(builder != NULL);

	if (builder->priv->grouping_ref > 0) {
		g_warning("Incorrect constraint grouping. Missed 'end_group'?");
		return NULL;
	}

	MidgardUser *user = midgard_connection_get_user(builder->priv->mgd);

	if (builder->priv->type == MIDGARD_TYPE_USER) {
		if (user && midgard_user_is_user(user)) {
			if (MGD_OBJECT_GUID (user) == NULL) {
				MIDGARD_ERRNO_SET(builder->priv->mgd, MGD_ERR_ACCESS_DENIED);
				g_warning("Type incompatible with Midgard Query Builder");
				return NULL;
			}

			GValue gval = {0, };
			g_value_init(&gval, G_TYPE_STRING);
			g_value_set_string(&gval, MIDGARD_DBOBJECT (user)->dbpriv->guid);

			midgard_query_builder_add_constraint(builder, "guid", "=", &gval);
		}
	}

	g_signal_emit (builder, MIDGARD_QUERY_BUILDER_GET_CLASS (builder)->signal_id_execution_start, 0);

	GList *list = midgard_core_qb_set_object_from_query(builder, select_type, NULL);

	if (list == NULL) {

		if (holder)
			holder->elements = 0;
	} else {
		
		if (holder)
			holder->elements = g_list_length(list);
	}

	g_signal_emit (builder, MIDGARD_QUERY_BUILDER_GET_CLASS (builder)->signal_id_execution_end, 0);

	return list;
}
Exemple #8
0
/**
 * midgard_blob_new: 
 * @attachment: #MidgardObject of MIDGARD_TYPE_ATTACHMENT type.
 * @encoding: file encoding
 * 
 * Default encoding is UTF-8. Set NULL @encoding if such is required. 
 *
 * Instatiate new Midgard Blob object for the given midgard_attachment object. 
 * This is almost the same constructor as g_object_new, but unlike that one,
 * midgard_blob_new requires MidgardObject (midgard_attachment) object's pointer.
 *
 * This constructor defines new relative path for attachment, if midgard_attachment 
 * is associated with midgard_blob and its location is empty. 
 * In any other case, location is not changed.
 * 
 * Returns: newly instatiated #MidgardBlob object or %NULL on failure
 */
MidgardBlob *midgard_blob_new (MidgardObject *attachment, const gchar *encoding)
{
	g_assert(attachment != NULL);
	
	MidgardConnection *mgd = MGD_OBJECT_CNC (attachment);

	if(mgd == NULL) {
		g_critical("MidgardConnection not found for given attachment");
		return NULL;
	}

	MIDGARD_ERRNO_SET(mgd, MGD_ERR_OK);

	const gchar *blobdir = MIDGARD_DBOBJECT (attachment)->dbpriv->mgd->priv->config->blobdir;
	if(!g_file_test(blobdir,G_FILE_TEST_EXISTS)) {
		midgard_set_error(mgd,
				MGD_GENERIC_ERROR,
				MGD_ERR_INTERNAL,
				" Blobs directory doesn't exist. %s", blobdir);
		return NULL;
	}

	if(!g_file_test(blobdir,G_FILE_TEST_IS_DIR)) {
		g_warning("Defined blobs directory is not directory");
		return NULL;
	}

	MidgardBlob *self = g_object_new(MIDGARD_TYPE_BLOB, NULL);
	self->priv->attachment = attachment;
	self->priv->mgd = mgd;
	self->priv->blobdir = g_strdup(blobdir);
	self->priv->channel = NULL;
	self->priv->encoding = NULL;
	if(encoding != NULL)
		self->priv->encoding = g_strdup(encoding);
	
	__get_filepath(self);

	if(self->priv->filepath == NULL) {		
		g_object_unref(self);
		return NULL;
	}
	
	return self;
}
static void 
midgard_dbobject_finalize (GObject *object)
{
	MidgardDBObject *self = MIDGARD_DBOBJECT(object);

	if (!self)
		return;

	if (!self->dbpriv)
		return;

	g_free((gchar *)self->dbpriv->guid);
	self->dbpriv->guid = NULL;

	g_free(self->dbpriv);
	self->dbpriv = NULL;

	parent_class->finalize (object);
}
void 
_midgard_metadata_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);

	MidgardDBObject *dbobject = MIDGARD_DBOBJECT (MIDGARD_METADATA (self)->priv->object);
	MgdSchemaTypeAttr *type_attr = MIDGARD_DBOBJECT_GET_CLASS (dbobject)->dbpriv->storage_data;
	MidgardMetadata *metadata = MIDGARD_METADATA (self);

	/* creator */
	const GValue *val = gda_data_model_get_value_at (model, column_id, row, NULL);
	midgard_core_metadata_set_creator (metadata, (GValue *) val);

	/* created */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_created (metadata, val);

	/* revisor */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_revisor (metadata, val);

	/* revised */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_revised (metadata, val);
	
	/* revision */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_revision (metadata, val);
	
	/* locker */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_locker (metadata, val);

	/* locked */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_locked (metadata, val);

	/* approver */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_approver (metadata, val);

	/* approved */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_approved (metadata, val);

	/* authors */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_authors (metadata, val);

	/* owner */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_owner (metadata, val);

	/* schedule_start */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_schedule_start (metadata, val);

	/* schedule_end */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_schedule_end (metadata, val);

	/* hidden */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_hidden (metadata, val);

	/* navnoentry */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_navnoentry (metadata, val);

	/* size */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_size (metadata, val);

	/* published */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_published (metadata, val);

	/* score */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_score (metadata, val);

	/* imported */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_imported (metadata, val);

	/* exported */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_exported (metadata, val);

	/* deleted */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_deleted (metadata, val);

	/* isapproved */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_isapproved (metadata, val);

	/* islocked */
	val = gda_data_model_get_value_at (model, ++column_id, row, NULL);
	midgard_core_metadata_set_islocked (metadata, val);
}
Exemple #11
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;	
}
gboolean _nodes2object(GObject *object, xmlNode *node, gboolean force)
{
	g_assert(object);
	g_assert(node);

	xmlNode *cur = NULL;
	GObject *prop_object;
	gchar *nodeprop = NULL;
	xmlChar *decoded;
	xmlParserCtxtPtr parser;
	MidgardObject *mobject = NULL;
	MidgardObject *lobject = NULL;
	MidgardReflectionProperty *mrp = NULL;
	const gchar *linktype = NULL;

	if(MIDGARD_IS_OBJECT(object)) {
		mobject = MIDGARD_OBJECT(object);
		MidgardObjectClass *klass =
			MIDGARD_OBJECT_GET_CLASS(mobject);
		if(klass)
			mrp = midgard_reflection_property_new(
					MIDGARD_DBOBJECT_CLASS(klass));
	}

	gpointer set_from_xml_func = MIDGARD_DBOBJECT_GET_CLASS(object)->dbpriv->set_from_xml_node;
	if(set_from_xml_func != NULL) {
		MIDGARD_DBOBJECT_GET_CLASS(object)->dbpriv->set_from_xml_node(MIDGARD_DBOBJECT(object), node);
		return TRUE;
	}

	for (cur = node; cur; cur = cur->next) {
		if (cur->type == XML_ELEMENT_NODE) {
		
			linktype = NULL;
	
			GParamSpec *pspec = g_object_class_find_property(
					G_OBJECT_GET_CLASS(G_OBJECT(object)), 
					(const gchar *)cur->name);
			if(pspec) {
				GValue pval = {0, };
				g_value_init(&pval, pspec->value_type);
				
				if(nodeprop)
					g_free(nodeprop);

				nodeprop = (gchar *)xmlNodeGetContent(cur);

				if(mrp) {
					if(midgard_reflection_property_is_link(
								mrp, pspec->name)){
						linktype =
							midgard_reflection_property_get_link_name(
									mrp, pspec->name);
					}
				}

				/* moved out from mrp condition check to avoid nested indents */

				if(linktype && midgard_is_guid(
							(const gchar *) nodeprop)){

					/* Just set property quickly, if property holds a guid */
					GType mtype = midgard_reflection_property_get_midgard_type(mrp, pspec->name);
					if (mtype == MGD_TYPE_GUID) {
						
						g_value_unset(&pval);
						g_object_set(mobject, (const gchar *)cur->name, nodeprop, NULL);
						continue;	
					}

					/* we can use nodeprop directly */
					lobject = midgard_schema_object_factory_get_object_by_guid (
							MIDGARD_DBOBJECT (mobject)->dbpriv->mgd,
							(const gchar *) nodeprop);

					if(!lobject && !force){
						g_object_unref(mrp);
						g_value_unset(&pval);
						midgard_set_error(MGD_OBJECT_CNC (mobject), 
								MGD_GENERIC_ERROR, 
								MGD_ERR_MISSED_DEPENDENCE, 
								" Can not import %s. "
								"No '%s' object identified by '%s'",
								G_OBJECT_TYPE_NAME(object),
								linktype, nodeprop); 
						g_clear_error(&MIDGARD_DBOBJECT (mobject)->dbpriv->mgd->err);	
						return FALSE;
					}
					
					/* When force parameter is set we do not translate guids to ids */
					if(force && !lobject && midgard_is_guid(
								(const gchar *) nodeprop)) {
						
						switch(pspec->value_type) {
							
							case G_TYPE_UINT:
								g_value_set_uint(&pval, 0);
								break;
							
							case G_TYPE_INT:
								g_value_set_int(&pval, 0);
								break;
							
							default:
								goto set_property_unchecked;
								break;
						}
						
						g_object_set_property(
								G_OBJECT(object),
								(const gchar *) cur->name,
								&pval);
						g_value_unset(&pval);
						continue;
					}

					GValue tval = {0, };
					g_value_init(&tval, pspec->value_type);

					g_object_get_property(G_OBJECT(lobject),
							"id", &tval);

					if(G_VALUE_TYPE(&pval) == G_TYPE_INT)
						g_value_transform((const GValue *) &tval,
								&pval);
					else
						g_value_copy((const GValue*) &tval,
								&pval);

					g_object_set_property(
							G_OBJECT(object),
							(const gchar *) cur->name,
							&pval);
					g_value_unset(&pval);
					g_object_unref(lobject);
					g_value_unset(&tval);
					continue;					
				}

				set_property_unchecked:
				switch (G_TYPE_FUNDAMENTAL (pspec->value_type)) {
				
					case G_TYPE_STRING:
						parser = xmlNewParserCtxt();
						decoded = 
							xmlStringDecodeEntities(parser,
									(const xmlChar *) nodeprop, 	
									XML_SUBSTITUTE_REF, 
									0, 0, 0);
						g_value_set_string(&pval, 
								(gchar *)decoded);
						g_free(decoded);
						xmlFreeParserCtxt(parser);
						break;

					case G_TYPE_INT:
						if(nodeprop) 
							g_value_set_int(&pval, 
									(gint)atoi((gchar *)nodeprop));
						break;

					case G_TYPE_UINT:
						if(nodeprop)
							g_value_set_uint(&pval,
									(guint)atoi((gchar *)nodeprop));
						break;

					case G_TYPE_FLOAT:
						g_value_set_float(&pval,
								(gfloat)atof((gchar *)nodeprop));
						break;

					case G_TYPE_BOOLEAN:
						g_value_set_boolean(&pval,
								(gboolean)atoi((gchar*)nodeprop));
						break;

					case G_TYPE_OBJECT:
						g_object_get(G_OBJECT(object),
								(const gchar *) cur->name,
								&prop_object, NULL);
						if (prop_object) {
							_nodes2object(prop_object, cur->children, force);	
							g_value_set_object(&pval, prop_object);
						} else {
							g_warning ("Failed to unserialize '%s' object property. Expected to be initialized by given '%s' instance", (const gchar *) cur->name, G_OBJECT_TYPE_NAME (object));
						}

						break;

					default:
						/* do nothing */
						break;						
				}
				g_object_set_property(
						G_OBJECT(object), 
						(const gchar *) cur->name, 
						&pval);
				g_value_unset(&pval);
			} else {
				g_warning("Undefined property '%s' for '%s'",
						cur->name, G_OBJECT_TYPE_NAME(object));
			}
		}		
	}

	if(nodeprop)
		g_free(nodeprop);

	if(mrp)
		g_object_unref(mrp);

	return TRUE;
}
static gboolean __import_blob_from_xml(	MidgardConnection *mgd,
					xmlDoc *doc, 
					xmlNode *node)
{
	gchar *content;
	struct stat statbuf;
	const gchar *guid = (const gchar *)xmlGetProp(node, BAD_CAST "guid");

	if (!guid) {
		MIDGARD_ERRNO_SET(mgd, MGD_ERR_INTERNAL);
		g_warning("Object's guid is empty. Can not import blob file.");
		g_free((gchar *)guid);
		xmlFreeDoc(doc);
		return FALSE;
	}

	if (!midgard_is_guid((const gchar *)guid)) {
		MIDGARD_ERRNO_SET(mgd, MGD_ERR_INTERNAL);
		g_warning("'%s' is not a valid guid", guid);
		g_free((gchar *)guid);
		xmlFreeDoc(doc);
		return FALSE;
	}

	MidgardObject *object = midgard_schema_object_factory_get_object_by_guid (mgd, guid);

	/* TODO , Add more error messages to inform about object state. 
	 * One is already set by midgard_object_class_get_object_by_guid */
	if (!object) {
		g_free((gchar *)guid);
		xmlFreeDoc(doc);
		return FALSE;
	}

	/* FIXME, define even macro to get blobdir ( core level only ) */
	gchar *blobdir = MIDGARD_DBOBJECT (object)->dbpriv->mgd->priv->config->blobdir;

	if (!blobdir || (*blobdir != '/')
			|| (stat(blobdir, &statbuf) != 0)
			|| !S_ISDIR(statbuf.st_mode)) {
		g_warning("Blobs directory is not set");
		g_free((gchar *)guid);
		xmlFreeDoc(doc);
		return FALSE;
	}

	gchar *location;
	gchar *blobpath = NULL;
	g_object_get(G_OBJECT(object), "location", &location, NULL);
	if (strlen(location) > 1) {
		blobpath = g_strconcat(blobdir, "/", location, NULL);
	}

	/* TODO, Find the way to get content and not its copy */
	/* node->content doesn't seem to hold it */
	content = (gchar *)xmlNodeGetContent(node);

	gsize content_length = (gsize) strlen(content);
	guchar *decoded = g_base64_decode(content, &content_length);
	g_free(content);

	FILE *fp = fopen(blobpath, "w+");
	if (NULL != fp) {
		g_free(decoded);
		g_free((gchar *)guid);
		xmlFreeDoc(doc);
		return FALSE;
	}
	size_t res_length = fwrite(decoded, sizeof(char), content_length, fp);
	fclose(fp);

	g_free(decoded);
	g_free((gchar *)guid);
	xmlFreeDoc(doc);

	if (res_length < content_length) {
		return FALSE;
	}

	return TRUE;
}
static gboolean 
_midgard_workspace_create (const MidgardWorkspaceManager *manager, MidgardWorkspaceStorage *ws, const gchar *_path, GError **error)
{
	g_return_val_if_fail (manager != NULL, FALSE);
	g_return_val_if_fail (ws != NULL, FALSE);

	const gchar *path = _path;
	if (path == NULL)
		path = "";

	MidgardWorkspace *self = MIDGARD_WORKSPACE (ws);
	MidgardConnection *mgd = manager->priv->mgd;
	MGD_OBJECT_CNC (self) = mgd;
	g_return_val_if_fail (mgd != NULL, FALSE);

	gchar *workspace_name = self->priv->name;
	if (workspace_name == NULL 
			|| (workspace_name != NULL && *workspace_name == '\0')) {
		g_set_error (error, MIDGARD_WORKSPACE_STORAGE_ERROR, MIDGARD_WORKSPACE_STORAGE_ERROR_INVALID_VALUE,
					"Invalid (empty or null) workspace's name"); 
		return FALSE;
	}

	GString *ws_path = g_string_new ("");
	g_string_append_printf (ws_path, "%s/%s", path, workspace_name);

	if (midgard_workspace_manager_path_exists (manager, ws_path->str)) {
		g_set_error (error, MIDGARD_WORKSPACE_STORAGE_ERROR, MIDGARD_WORKSPACE_STORAGE_ERROR_NAME_EXISTS, 
				"WorkspaceStorage at path '%s/%s' already exists", 
				path, workspace_name);
		g_string_free (ws_path, TRUE);
		return FALSE;
	}
	
	GError *err = NULL;
	gint up_id = 0;

	/* Ignore empty path, we're going to create root workspace */
	if (*path != '\0') {
		up_id = midgard_core_workspace_get_id_by_path (mgd, path, NULL, &err);	
		if (err && err->code) {
			if (err->code == MIDGARD_WORKSPACE_STORAGE_ERROR_OBJECT_NOT_EXISTS) {
				if (up_id == -1) 
					up_id = 0;
				g_clear_error (&err);	
			} else if (err->code == MIDGARD_WORKSPACE_STORAGE_ERROR_NAME_EXISTS
					|| err->code == MIDGARD_WORKSPACE_STORAGE_ERROR_PATH_EXISTS) {
				g_clear_error (&err);
			} else {
				g_propagate_error (error, err);
				g_string_free (ws_path, TRUE);
				return FALSE;
			}
		}
	}

	/* TODO, set parent workspace, if needed 
	 * MidgardWorkspaceContext *context = midgard_workspace_context_new (); */

	/* Create, set guid and up id */
	MIDGARD_DBOBJECT(self)->dbpriv->guid = (const gchar *) midgard_guid_new (mgd);
	self->priv->up_id = up_id;
	if (midgard_core_query_create_dbobject_record (MIDGARD_DBOBJECT (self))) {
		/* TODO ?, emit created signal */
		/* Refresh available workspaces model */
		midgard_core_workspace_list_all (mgd, FALSE);

		/* Get id of newly created object */
		guint row_id;
		gint id = midgard_core_workspace_get_col_id_by_name (mgd, self->priv->name, MGD_WORKSPACE_FIELD_IDX_ID, self->priv->up_id, &row_id);
		if (id < 1) {
			g_warning ("Newly created workspace (%s) id is not unique (%d)", ws_path->str, id);
			/* TODO, set error and delete workspace from database */
			g_string_free (ws_path, TRUE);
			return FALSE;
		}
		self->priv->id = id;
		g_string_free (ws_path, TRUE);
		return TRUE;
	}

	g_string_free (ws_path, TRUE);

	/* Create failed, reset values */
	g_free ((gchar *)MGD_OBJECT_GUID (self));
	MGD_OBJECT_GUID (self) = NULL;

	self->priv->up_id = 0;
	self->priv->id = 0;

	/* FIXME, Set internal error */
	return FALSE;
}
/**
 * midgard_replicator_import_from_xml:
 * @mgd: #MidgardConnection instance
 * @xml: data buffer which holds serialized object
 * @force: toggle to force import
 *
 * This method tries to import all objects which could be unserialized from gievn xml.
 * It's not atomic. Check error code returned from midgard_connection_get_error().
 *
 */ 
void 
midgard_replicator_import_from_xml (MidgardConnection *mgd,  const gchar *xml, gboolean force)
{
	g_return_if_fail (mgd != NULL);
	g_return_if_fail (xml != NULL);
	
	xmlDoc *doc = NULL;
	xmlNode *root_node = NULL;
	midgard_core_object_get_xml_doc(mgd, xml, &doc, &root_node);
	
	if(doc == NULL || root_node == NULL)
		return;

	xmlNodePtr child = _get_type_node(root_node->children);
	if(!child) {
		g_warning("Can not get midgard type name from the given xml");
		xmlFreeDoc(doc);
		return;
	}

	GType object_type = g_type_from_name((const gchar *)child->name);
	
	if(object_type == MIDGARD_TYPE_BLOB) {
		/* it will destroy xmlDoc */
		__import_blob_from_xml(mgd, doc, child);
		return;
	}

	xmlChar *attr, *guid_attr;
	MidgardObject *dbobject;

	for(; child; child = _get_type_node(child->next)) {
		
		attr = xmlGetProp(child, BAD_CAST "purge");
		guid_attr = xmlGetProp(child, BAD_CAST "guid");

		if(attr && g_str_equal(attr, "yes")) {
			
			dbobject = midgard_schema_object_factory_get_object_by_guid (mgd, (const gchar *)guid_attr);

			if(dbobject || 
					( !dbobject && 
					 (mgd->errnum == MGD_ERR_OBJECT_DELETED)
					 )) {
		
				midgard_object_purge(dbobject, FALSE);
				if(dbobject)
					g_object_unref(dbobject);
				xmlFree(attr);
				xmlFree(guid_attr);
				continue;
			}
		}

		xmlFree(attr);

		MidgardObject *object =
			midgard_object_new(mgd, (const gchar *)child->name, NULL);
		if(!object) {
			g_warning("Can not create %s instance", child->name);
			xmlFreeDoc(doc);
			xmlFree(attr);
			xmlFree(guid_attr);
			continue;
		}

		if (guid_attr) {
			MGD_OBJECT_GUID (object) = (const gchar *)g_strdup((gchar *)guid_attr);
		}

		if(!_nodes2object(G_OBJECT(object), child->children, force)) {
			xmlFree(guid_attr);
			g_object_unref(object);
			continue;
		}			
		
		if (!midgard_replicator_import_object (MIDGARD_DBOBJECT (object), force)) {

			xmlFree (guid_attr);
			g_object_unref (object);
			continue;

		} else {

			xmlFree (guid_attr);
			g_object_unref (object);
		}
	}

	xmlFreeDoc (doc);
}
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;
}
static void
_metadata_get_property (GObject *object, guint property_id,
        GValue *value, GParamSpec *pspec)
{    
	MidgardMetadata *self =	(MidgardMetadata *) object;

	if (MIDGARD_DBOBJECT_GET_CLASS (object)->dbpriv->get_property (MIDGARD_DBOBJECT (object), pspec->name, value))
		return;

	switch (property_id) {
		
		case MIDGARD_METADATA_CREATOR:
			g_value_set_string (value, self->priv->creator);	
			break;
			
		case MIDGARD_METADATA_CREATED:
			g_value_set_boxed (value, self->priv->created);
			break;
			
		case MIDGARD_METADATA_REVISOR:
			g_value_set_string (value, self->priv->revisor);
			break;
			
		case MIDGARD_METADATA_REVISED:
			g_value_set_boxed (value, self->priv->revised);
			break;
			
		case MIDGARD_METADATA_LOCKER:
			g_value_set_string (value, self->priv->locker);
			break;
			
		case MIDGARD_METADATA_LOCKED:
			g_value_set_boxed (value, self->priv->locked);
			break;
			
		case MIDGARD_METADATA_APPROVER:
			g_value_set_string (value, self->priv->approver);
			break;
			
		case MIDGARD_METADATA_APPROVED:    
			g_value_set_boxed (value, self->priv->approved);
			break;
			
		case MIDGARD_METADATA_REVISION:             
			g_value_set_uint (value, self->priv->revision);            
			break;
			
		case MIDGARD_METADATA_AUTHORS:
			g_value_set_string (value, self->priv->authors);
			break;
			
		case MIDGARD_METADATA_OWNER:
			g_value_set_string (value, self->priv->owner);
			break;
			
		case MIDGARD_METADATA_SCHEDULE_START:
			g_value_set_boxed (value, self->priv->schedule_start);
			break;
			
		case MIDGARD_METADATA_SCHEDULE_END:
			g_value_set_boxed (value, self->priv->schedule_end);
			break;
			
		case MIDGARD_METADATA_HIDDEN:
			g_value_set_boolean (value, self->priv->hidden);
			break;
			
		case MIDGARD_METADATA_NAV_NOENTRY:
			g_value_set_boolean (value, self->priv->nav_noentry);
			break;
			
		case MIDGARD_METADATA_SIZE:
			g_value_set_uint(value,  self->priv->size);
			break;
			
		case MIDGARD_METADATA_PUBLISHED:
			g_value_set_boxed (value, self->priv->published);
			break;

		case MIDGARD_METADATA_SCORE:
			g_value_set_int (value, self->priv->score);
			break;

		case MIDGARD_METADATA_EXPORTED:
			g_value_set_boxed (value, self->priv->exported);
			break;

		case MIDGARD_METADATA_IMPORTED:
			g_value_set_boxed (value, self->priv->imported);
			break;

		case MIDGARD_METADATA_DELETED:
			g_value_set_boolean (value, self->priv->deleted);
			break;
		
		case MIDGARD_METADATA_ISLOCKED:
			g_value_set_boolean (value, self->priv->is_locked);
			break;
		
		case MIDGARD_METADATA_ISAPPROVED:
			g_value_set_boolean (value, self->priv->is_approved);
			break;

		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(object,property_id,pspec);
			break;
	}
}