static PHP_METHOD(midgard_object_class, get_object_by_guid) { RETVAL_FALSE; MidgardConnection *mgd = mgd_handle(TSRMLS_C); CHECK_MGD(mgd); char *guid; int guid_length; const gchar *type_name; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &guid, &guid_length) == FAILURE) return; MidgardObject *object = midgard_schema_object_factory_get_object_by_guid(mgd, guid); if (!object) { php_midgard_error_exception_throw(mgd TSRMLS_CC); return; } type_name = G_OBJECT_TYPE_NAME(G_OBJECT(object)); zend_class_entry *ce = zend_fetch_class((gchar *)type_name, strlen(type_name), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); if (ce == NULL) { php_error(E_WARNING, "Can not find %s class", type_name); return; } php_midgard_gobject_new_with_gobject(return_value, ce, G_OBJECT(object), TRUE TSRMLS_CC); }
static PyObject * pymidgard_schema_object_factory_get_object_by_guid (PyGObject *self, PyObject *args) { gchar *guid; if (!PyArg_ParseTuple (args, "s", &guid)) return NULL; MidgardConnection *mgd = _py_midgard_connection_singleton_get (); MidgardObject *mobject = midgard_schema_object_factory_get_object_by_guid (mgd, guid); if (mobject) return Py_BuildValue ("O", pygobject_new (G_OBJECT (mobject))); Py_RETURN_NONE; }
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; }
/** * 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); }
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 PHP_METHOD(midgard_object_class, factory) { MidgardConnection *mgd = mgd_handle(TSRMLS_C); CHECK_MGD(mgd); char *class_name; int class_name_length; zval *zvalue = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &class_name, &class_name_length, &zvalue) == FAILURE) return; zend_class_entry **pce = NULL; #if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION > 3 if (zend_lookup_class_ex(class_name, class_name_length, NULL, 1, &pce TSRMLS_CC) == FAILURE) { #else if (zend_lookup_class_ex(class_name, class_name_length, 1, &pce TSRMLS_CC) == FAILURE) { #endif php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can not find %s class", class_name); return; } zend_class_entry *ce = *pce; object_init_ex(return_value, ce); /* Initialize new object for which QB has been created for */ /* Call class constructor on given instance */ if (zvalue == NULL) { zend_call_method_with_0_params(&return_value, ce, &ce->constructor, "__construct", NULL); } else { zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, zvalue); } } ZEND_BEGIN_ARG_INFO_EX(arginfo_midgard_object_class_factory, 0, 0, 1) ZEND_ARG_INFO(0, classname) ZEND_ARG_INFO(0, id) ZEND_END_ARG_INFO() static PHP_METHOD(midgard_object_class, get_object_by_guid) { RETVAL_FALSE; MidgardConnection *mgd = mgd_handle(TSRMLS_C); CHECK_MGD(mgd); char *guid; int guid_length; const gchar *type_name; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &guid, &guid_length) == FAILURE) return; MidgardObject *object = midgard_schema_object_factory_get_object_by_guid(mgd, guid); if (!object) { php_midgard_error_exception_throw(mgd TSRMLS_CC); return; } type_name = G_OBJECT_TYPE_NAME(G_OBJECT(object)); zend_class_entry *ce = zend_fetch_class((gchar *)type_name, strlen(type_name), ZEND_FETCH_CLASS_AUTO TSRMLS_CC); if (ce == NULL) { php_error(E_WARNING, "Can not find %s class", type_name); return; } php_midgard_gobject_new_with_gobject(return_value, ce, G_OBJECT(object), TRUE TSRMLS_CC); }