gchar *midgard_core_object_to_xml(GObject *object)
{
	g_assert(object);
	
	xmlDocPtr doc = NULL; 
	xmlNodePtr root_node = NULL;
		
	LIBXML_TEST_VERSION;
		
	doc = xmlNewDoc(BAD_CAST "1.0");
	root_node = xmlNewNode(NULL, 
			BAD_CAST "midgard_object");
	xmlNewNs(root_node,
			BAD_CAST MIDGARD_OBJECT_HREF,
			NULL);
	xmlNodePtr object_node = 
		xmlNewNode(NULL, BAD_CAST G_OBJECT_TYPE_NAME(G_OBJECT(object)));
	/* Add purged info */
	/* We could add this attribute in _write_nodes function 
	 * but this could corrupt xsd compatibility for midgard_metadata nodes.
	 * So it's added here and for every multilingual content */
	xmlNewProp(object_node, BAD_CAST "purge", BAD_CAST "no");
	xmlAddChild(root_node, object_node);
	xmlDocSetRootElement(doc, root_node);
	_write_nodes(G_OBJECT(object), object_node);

	xmlChar *buf;
	gint size;
	xmlDocDumpFormatMemoryEnc(doc, &buf, &size, "UTF-8", 1);
	
	xmlFreeDoc(doc);
	xmlCleanupParser();

	return (gchar*) buf;
}
Example #2
0
uint8_t ngdb_write(graph_t *g, char *f) {

  ngdb_t *ngdb;

  ngdb = ngdb_create(
    f,
    graph_num_nodes(g),
    NGDB_HDR_DATA_SIZE,
    sizeof(graph_label_t),
    sizeof(double));

  if (ngdb == NULL)          goto fail;
  if (_write_hdr  (ngdb, g)) goto fail;
  if (_write_nodes(ngdb, g)) goto fail;
  if (_write_refs (ngdb, g)) goto fail;
  if (ngdb_close(ngdb))      goto fail;

  return 0;

fail:
  if (ngdb != NULL) ngdb_close(ngdb);
  return 1;
}
static void _write_nodes(GObject *object, xmlNodePtr node)
{
	g_assert(object);
	g_assert(node);

	guint prop_n;
	MidgardObject *mgdobject = (MidgardObject *)object;
	MidgardReflectionProperty *mrp = NULL;
	MidgardObjectClass *klass = NULL;
	GParamSpec **pspec = g_object_class_list_properties(
			G_OBJECT_GET_CLASS(G_OBJECT(object)), &prop_n);
	
	if(MIDGARD_IS_OBJECT(object)) {
		klass = 
			MIDGARD_OBJECT_GET_CLASS(object);
		if(klass)
			mrp = midgard_reflection_property_new(
					MIDGARD_DBOBJECT_CLASS(klass));
	}

	GValue pval = {0, }, *lval;
	GString *gstring;
	gchar *strprop = NULL;
	xmlChar *escaped;
	guint i;
	xmlNodePtr op_node = NULL;
	const gchar *linktype;
	MidgardCollector *mc;
	guint _uint;
	gint _int;
	GObject *_object;

	if(MIDGARD_IS_OBJECT(mgdobject)) {

		gint object_action = -1;	

		if(MGD_OBJECT_GUID (mgdobject)) {

			GString *_sql = g_string_new(" ");
			g_string_append_printf(_sql, "guid = '%s' ",	
					MGD_OBJECT_GUID (mgdobject));
			
			gchar *tmpstr = g_string_free(_sql, FALSE);
						
			GValue *avalue =
				midgard_core_query_get_field_value(
						MGD_OBJECT_CNC (mgdobject),	
						"object_action",
						"repligard", 
						(const gchar*)tmpstr);

			if(avalue) {
				
				MIDGARD_GET_UINT_FROM_VALUE(object_action, avalue);
				g_value_unset(avalue);
				g_free(avalue);
			}
			
			g_free(tmpstr);
		}

		gchar *_action;
		if(object_action > -1) {
			
			switch(object_action) {
				
				case MGD_OBJECT_ACTION_CREATE:
					_action = "created";		
					break;
				
				case MGD_OBJECT_ACTION_UPDATE:
					_action = "updated";
					break;
				
				case MGD_OBJECT_ACTION_DELETE:
					_action = "deleted";
					break;
				
				case MGD_OBJECT_ACTION_PURGE:
					_action = "purged";
					break;
				
				default:
					_action = "none";
					break;
			}
			
			xmlNewProp(node, BAD_CAST "action",
					BAD_CAST _action);
		}
	}

	for(i = 0; i < prop_n; i++) {
		
		g_value_init(&pval,pspec[i]->value_type);
		g_object_get_property(G_OBJECT(object), 
				pspec[i]->name, &pval);

		if(g_str_equal("guid", pspec[i]->name)) {
			/* Add guid attribute */
			xmlNewProp(node, BAD_CAST "guid", 
					BAD_CAST MGD_OBJECT_GUID (object));
			g_value_unset(&pval);
			continue;
		}
				
		/* Object is not fetched from database. Skip references */
		if(MGD_OBJECT_GUID (mgdobject) == NULL)
			goto export_unchecked_property;

		/* If property is a link we need to query guid 
		 * which identifies link object. Only if property 
		 * is not of guid or string type */
		if(mrp){	
			if(midgard_reflection_property_is_link(mrp, 
						pspec[i]->name)){

				lval = g_new0(GValue, 1);
				switch(pspec[i]->value_type) {
					
					case G_TYPE_UINT:
						g_value_init(lval, G_TYPE_UINT);
						_uint = g_value_get_uint(&pval);
						if(!_uint){
							g_value_unset(lval);
							g_free(lval);
							goto export_unchecked_property;
						}
						g_value_set_uint(lval, _uint);
						break;

					case G_TYPE_INT:
						g_value_init(lval, G_TYPE_INT);
						_int = g_value_get_int(&pval);
						if(!_int){
							g_value_unset(lval);
							g_free(lval);
							goto export_unchecked_property;
						}
						g_value_set_int(lval, _int);
						break;

					default:
						g_free(lval);
						goto export_unchecked_property;
				}
					
				linktype = 
					midgard_reflection_property_get_link_name(
							mrp, pspec[i]->name);
				
				if(linktype){
					mc = midgard_collector_new(
							MGD_OBJECT_CNC (mgdobject),
							linktype,
							"id",
							lval);
					
					midgard_collector_set_key_property(
							mc,
							"guid", NULL);
					if(!midgard_collector_execute(mc)){
						g_object_unref(mc);
						g_value_unset(&pval);
						continue;
					}				
					gchar **linkguid = 
						midgard_collector_list_keys(mc);
					if(linkguid){
						if(linkguid[0])
							strprop = g_strdup(linkguid[0]);
					}
					if(!strprop)
						strprop = g_strdup("");
					
					/* Create node */
					escaped = xmlEncodeEntitiesReentrant(
							NULL, (const xmlChar*)strprop);
					xmlNewTextChild(node, NULL,
							BAD_CAST pspec[i]->name,
							BAD_CAST escaped);
					
					g_free(linkguid);
					g_free(strprop);
					g_free(escaped);
					g_object_unref(mc);	
				}
				g_value_unset(&pval);
				continue;
			}
		}	
		
		export_unchecked_property:
		switch (G_TYPE_FUNDAMENTAL(pspec[i]->value_type)) {
			
			case G_TYPE_STRING:				
				strprop = g_value_dup_string(&pval);
				if(!strprop)
					strprop = g_strdup("");
				escaped = xmlEncodeEntitiesReentrant(
						NULL, (const xmlChar*)strprop);
				xmlNewTextChild(node, NULL, 
						BAD_CAST pspec[i]->name,
						BAD_CAST escaped);
			         
				g_free(strprop);
				g_free(escaped);
				break;

			case G_TYPE_INT:
				gstring = g_string_new("");
				g_string_append_printf(gstring,
						"%d", g_value_get_int(&pval));
				xmlNewChild(node, NULL, 
						BAD_CAST pspec[i]->name,
						BAD_CAST (xmlChar *)gstring->str);
				g_string_free (gstring, TRUE);
				break;

			case G_TYPE_UINT:
				gstring = g_string_new("");
				g_string_append_printf(gstring,
						"%d", g_value_get_uint(&pval));
				xmlNewChild(node, NULL, 
						BAD_CAST pspec[i]->name,
						BAD_CAST (xmlChar *)gstring->str);
				g_string_free (gstring, TRUE);
				break;

			case G_TYPE_FLOAT:
				gstring = g_string_new("");
				g_string_append_printf(gstring,
						"%g", g_value_get_float(&pval));
				xmlNewChild(node, NULL,
						BAD_CAST pspec[i]->name,
						BAD_CAST (xmlChar *)gstring->str);
				g_string_free (gstring, TRUE);
				break;

			case G_TYPE_BOOLEAN:
				if(g_value_get_boolean(&pval))
					strprop = "1";
				else 
					strprop = "0";

				xmlNewChild(node, NULL,
						BAD_CAST pspec[i]->name,
						BAD_CAST (xmlChar *)strprop);
				break;

			case G_TYPE_OBJECT:
	
				_object = g_value_get_object (&pval);
				
				if (_object) {
					op_node = xmlNewNode(NULL, BAD_CAST pspec[i]->name);
					_write_nodes(_object, op_node);
					xmlAddChild(node, op_node);
				}
				break;

			default:

				if (pspec[i]->value_type == MIDGARD_TYPE_TIMESTAMP) {
		
					GValue strval = {0, };
					g_value_init (&strval, G_TYPE_STRING);
					g_value_transform (&pval, &strval);
					xmlNewChild(node, NULL, 
						BAD_CAST pspec[i]->name,
						BAD_CAST (xmlChar *)g_value_get_string (&strval));
					g_value_unset (&strval);

				} else {
					g_warning ("midgard_replicator_serialize: unhandled %s property type (%s)", 
							pspec[i]->name, g_type_name (pspec[i]->value_type)); 
				}
		}
		g_value_unset(&pval);
	}

	g_free(pspec);

	if(mrp)
		g_object_unref(mrp);
}