/** * midgard_query_storage_new: * @classname: name of the #MidgardDBObject derived class * * Initializes new object which represents #MidgardDBObject derived one's storage * * Returns: new #MidgardQueryStorage or %NULL on failure * Since: 10.05 */ MidgardQueryStorage* midgard_query_storage_new (const gchar *classname) { g_return_val_if_fail (classname != NULL, NULL); GType type = g_type_from_name (classname); if (!type) { g_warning ("Class %s is not registered in GType system", classname); return NULL; } GObjectClass *klass = G_OBJECT_CLASS (g_type_class_peek (type)); if (!klass) { g_warning ("Can not find %s class", classname); return NULL; } g_return_val_if_fail (MIDGARD_IS_DBOBJECT_CLASS (klass), NULL); MidgardDBObjectClass *dbklass = MIDGARD_DBOBJECT_CLASS (klass); MidgardQueryStorage *self = g_object_new (MIDGARD_TYPE_QUERY_STORAGE, "dbclass", classname, NULL); self->priv->klass = dbklass; self->priv->table = midgard_core_class_get_table (dbklass); return self; }
static void __statement_update_add_metadata_fields (MidgardDBObjectClass *klass, GString *sql) { MidgardMetadataClass *mklass = MGD_DBCLASS_METADATA_CLASS (klass); if (!mklass) return; guint i; guint n_prop; GParamSpec **pspecs = g_object_class_list_properties (G_OBJECT_CLASS (mklass), &n_prop); if (!pspecs) return; for (i = 0; i < n_prop; i++) { const gchar *col_name = midgard_core_class_get_property_colname (MIDGARD_DBOBJECT_CLASS (mklass), pspecs[i]->name); if (!col_name) continue; const gchar *type_name = g_type_name (pspecs[i]->value_type); if (pspecs[i]->value_type == MIDGARD_TYPE_TIMESTAMP) type_name = "string"; g_string_append_printf (sql, ", %s=##%s::%s", col_name, col_name, type_name); } g_free (pspecs); }
/** * midgard_query_builder_new(): * @mgd: #MidgardConnection instance * @classname: any #MidgardDBObjectClass derived class' name * * Returns: new #MidgardQueryBuilder instance or %NULL if target class is not registered in GType system * or it's not #MidgardDBObjectClass class derived one. */ MidgardQueryBuilder *midgard_query_builder_new( MidgardConnection *mgd, const gchar *classname) { g_assert(mgd != NULL); g_assert(classname != NULL); GType class_type = g_type_from_name(classname); if(!__type_is_valid(class_type)) { g_warning("Can not initialize Midgard Query Builder for '%s'. It's not registered GType system class", classname); MIDGARD_ERRNO_SET(mgd, MGD_ERR_INVALID_OBJECT); return NULL; } MidgardQueryBuilder *builder = g_object_new(MIDGARD_TYPE_QUERY_BUILDER, NULL); builder->priv = midgard_query_builder_private_new(); builder->priv->mgd = mgd; builder->priv->type = g_type_from_name(classname); builder->priv->include_deleted = FALSE; builder->priv->error = 0; MidgardDBObjectClass *klass = (MidgardDBObjectClass*) g_type_class_peek(class_type); if (klass->dbpriv == NULL) { g_warning("Given %s class has no storage definitions", g_type_name(class_type)); g_object_unref(builder); return NULL; } builder->priv->schema = klass->dbpriv->storage_data; gchar **tables = g_strsplit(midgard_core_class_get_tables(MIDGARD_DBOBJECT_CLASS(klass)), ",", 0); guint i = 0; while(tables[i] != NULL) { midgard_core_qb_add_table(builder, (const gchar *)g_strchug(tables[i])); i++; } g_strfreev(tables); builder->priv->offset = 0; builder->priv->limit = G_MAXUINT; if (builder->priv->type && builder->priv->schema) { return builder; } else { g_object_unref(builder); return NULL; } }
/** * midgard_query_builder_add_constraint(): * @builder: #MidgardQueryBuilder instance * @name: property name used for this constraint * @op: comparison operator * @value: value used in comparison * * Adds a constraint to the given query builder. The constraint is * expressed as a triple of a field name, a comparison operator, and * a comparison value. * * <para> * @name referes to a property of the queried Midgard object class. * For example: #MidgardQueryBuilder has been initialized for person * class which has lastname property registered. * <example> * <programlisting> * * GValue value = {0, }; * g_value_init(&value, G_TYPE_STRING); * g_value_set_string(&value, "smith"); * * midgard_query_builder_add_constraint(builder, "lastname", "=", &value); * * </programlisting> * </example> * </para> * <para> * It also can be name of the linked class property or reserved one. * A dot '.' is used to separate properties for special constraints. * If such special constraint property is used, #MidgardQueryBuilder * performs right join. * <itemizedlist> * <listitem><para> * First property is the one registered for given class which is a link * to property of different class. Second is a property of target class. * For example: person object has property 'friend' which holds some identifier * (id or guid) to friend class property, and friend class has property 'nick'. * In such case we can use constraint and comparison using friend property, * even if #MidgardQueryBuilder has been initialized for person class. * <example> * <programlisting> * * GValue value = {0, }; * g_value_init(&value, G_TYPE_STRING); * g_value_set_string(&value, "Lancelot"); * * midgard_query_builder_add_constraint(builder, "friend.nick", "=", &value); * * </programlisting> * </example> * </para></listitem> * <listitem><para> * There are three reserved words which have special meaning for query builder. * 'metadata', 'parameter' and 'attachment'. If one of them is used, query builder * will make (if necessary) right join and query objects against dependent class table. * <example> * <programlisting> * * GValue value = {0, }; * g_value_init(&value, G_TYPE_STRING); * g_value_set_string(&value, "avatar"); * * midgard_query_builder_add_constraint(builder, "attachment.name", "=", &value); * * </programlisting> * </example> * </para></listitem> * </itemizedlist> * </para> * * <para> * The comparison operator is a string representation of the requested comparison. * Available operators are =, <>, <, >, <=, >=, LIKE, NOT LIKE, IN, INTREE. * </para> * * <para> * The given @value is copied and converted into the property type before comparison. * </para> * * Returns: %TRUE if constraint is valid, %FALSE otherwise */ gboolean midgard_query_builder_add_constraint( MidgardQueryBuilder *builder, const gchar *name, const gchar *op, const GValue *value) { g_assert(builder); g_assert(name); g_assert(op); g_assert(value); MidgardCoreQueryConstraint *constraint = midgard_core_query_constraint_new(); midgard_core_query_constraint_set_builder(constraint, builder); midgard_core_query_constraint_set_class(constraint, MIDGARD_DBOBJECT_CLASS(g_type_class_peek(builder->priv->type))); if(!midgard_core_query_constraint_add_operator(constraint, op)) return FALSE; if(!midgard_core_query_constraint_parse_property(&constraint, MIDGARD_DBOBJECT_CLASS(g_type_class_peek(builder->priv->type)), name)) return FALSE; if(!midgard_core_query_constraint_add_value(constraint, value)) return FALSE; midgard_core_query_constraint_build_condition(constraint); /* FIXME, table should be stored per every constraint, order, whatever */ midgard_core_qb_add_table(builder, constraint->priv->prop_left->table); if(builder->priv->grouping_ref > 0) { MidgardGroupConstraint *group = (MidgardGroupConstraint *)builder->priv->group_constraint; midgard_group_constraint_add_constraint(group, constraint); return TRUE; } midgard_core_qb_add_constraint(builder, constraint); return TRUE; }
static const gchar *_collector_find_class_property( MidgardCollector *self, const gchar *propname) { const gchar *table_field = midgard_core_class_get_property_tablefield( MIDGARD_DBOBJECT_CLASS(self->priv->klass), propname); /* Let's try metadata class */ if(table_field == NULL) { MidgardMetadataClass *mklass = (MidgardMetadataClass*) g_type_class_peek(g_type_from_name("MidgardMetadata")); table_field = midgard_core_class_get_property_tablefield( MIDGARD_DBOBJECT_CLASS(mklass), propname); } return table_field; }
gboolean _midgard_metadata_dbpriv_get_property (MidgardDBObject *self, const gchar *name, GValue *value) { gchar *datamodel_property = g_strconcat ("metadata_", name, NULL); MidgardDBObject *dbobject = MIDGARD_METADATA(self)->priv->object; if (!dbobject || !dbobject->dbpriv) return FALSE; gboolean rv = MIDGARD_DBOBJECT_CLASS (__parent_class)->dbpriv->get_property (dbobject, datamodel_property, value); g_free (datamodel_property); return rv; }
gchar* get_real_table_field (MidgardQueryExecutor *executor, MidgardSqlQueryColumn *column) { g_return_val_if_fail (executor != NULL, NULL); g_return_val_if_fail (column != NULL, NULL); MidgardConnection *mgd = executor->priv->mgd; g_return_val_if_fail (executor != NULL, NULL); /* Set default dbclass by default */ MidgardDBObjectClass *dbklass = NULL; if (executor->priv->storage) dbklass = executor->priv->storage->priv->klass; gchar *classname = NULL; gchar *pname = NULL; MidgardQueryStorage *storage = NULL; /* Set property's dbclass if defined */ MidgardQueryProperty *qproperty = midgard_query_column_get_query_property (MIDGARD_QUERY_COLUMN(column), NULL); g_object_get (qproperty, "storage", &storage, "property", &pname, NULL); if (storage) g_object_get (storage, "dbclass", &classname, NULL); g_object_unref (qproperty); if (classname) { GType dbtype = g_type_from_name (classname); /* TODO , handle invalid type error */ dbklass = MIDGARD_DBOBJECT_CLASS (g_type_class_peek (dbtype)); } /* Get real fieldname */ const gchar *fieldname = (const gchar *)pname; if (dbklass) fieldname = midgard_core_class_get_property_colname (dbklass, pname); const gchar *qualifier = midgard_query_column_get_qualifier (MIDGARD_QUERY_COLUMN (column), NULL); if (*qualifier == '\0') qualifier = NULL; gchar *table_alias_field = g_strdup_printf("%s%s%s", qualifier ? qualifier : "", qualifier ? "." : "", fieldname); g_free (classname); g_free (pname); return table_alias_field; }
MidgardQueryOrder *midgard_core_query_order_new( MidgardQueryBuilder *builder, const gchar *name, const gchar *dir) { g_assert(builder != NULL); g_assert(name != NULL); const gchar *user_dir = dir; if(user_dir == NULL) user_dir = "ASC"; guint i = 0; while(valid_dirs[i] != NULL) { if (g_str_equal(user_dir, valid_dirs[i])) break; i++; } if(valid_dirs[i] == NULL) { g_warning("Invalid order direction: %s", dir); return NULL; } MidgardQueryOrder *order = g_new(MidgardQueryOrder, 1); order->constraint = midgard_core_query_constraint_new(); order->constraint->priv->order_dir = g_strdup(dir); /* Explicitly set builder. It's required for proper constraint's property "parser". * Without builder, implicit joins (for example) are not added */ midgard_core_query_constraint_set_builder(order->constraint, builder); MidgardDBObjectClass *klass = MIDGARD_DBOBJECT_CLASS(g_type_class_peek(builder->priv->type)); if(!midgard_core_query_constraint_parse_property(&(order->constraint), klass, name)) { midgard_core_query_order_free(order); return FALSE; } midgard_core_qb_add_table(builder, order->constraint->priv->prop_left->table); return order; }
static void __mgdschematype_from_node(xmlNode *node, GSList **list) { g_assert(node != NULL); xmlChar *viewname = xmlGetProp(node, (const xmlChar *)MGD_VIEW_RW_NAME); if (!viewname) __view_error(node, "Empty view name. Can not define any type.", NULL); MgdSchemaTypeAttr *type = midgard_core_schema_type_attr_new(); type->name = g_strdup((gchar *)viewname); type->is_view = TRUE; /* Determine base view table */ xmlChar *table = xmlGetProp(node, (const xmlChar *) TYPE_RW_TABLE); /* Table not defined, try classtable */ if (!table) { xmlChar *classname = xmlGetProp(node, (const xmlChar *) "class"); if (!classname) __view_error(node, "'table' or 'class' attribute not found", NULL); MidgardDBObjectClass *dbklass = MIDGARD_DBOBJECT_CLASS(g_type_class_peek(g_type_from_name((const gchar *)classname))); table = (xmlChar *)g_strdup(midgard_core_class_get_table(dbklass)); if (!table) __view_error(node, "NULL table for %s class", classname); xmlFree(classname); } midgard_core_schema_type_set_table(type, (const gchar *)table); xmlFree(table); __get_view_properties(node, type); __get_view_joins(node, type); __get_view_constraints(node, type); midgard_core_schema_type_build_static_sql(type); *list = g_slist_append(*list, type); xmlFree(viewname); }
gboolean php_midgard_is_property_timestamp(MidgardDBObjectClass *klass, const gchar *property) { g_assert(klass != NULL); g_assert(property != NULL); MidgardReflectionProperty *mrp = midgard_reflection_property_new(MIDGARD_DBOBJECT_CLASS(klass)); GType midgard_type = midgard_reflection_property_get_midgard_type(mrp, property); g_object_unref(mrp); if (midgard_type == MGD_TYPE_TIMESTAMP) return TRUE; return FALSE; }
/** * midgard_query_builder_add_constraint_with_property: * @builder: #MidgardQueryBuilder instance * @property_a: property name * @op: comparison operator * @property_b: property name * * Adds named property constraint to the given query builder. * Unlike add_constraint method, this one accepts property name * instead of scalar value. The difference is that with add_constraint * method you can compare property with particular value, while using * add_constraint_with_property method you can compare two different * properties without any need to know their values. * For example, you should use this method if you want to select only * those objects which has been revised after publication time, and particular * date doesn't matter. * * <example> * <programlisting> * * midgard_query_builder_add_constraint_with_property(builder, "metadata.revised", ">", "metadata.published"); * * </programlisting> * </example> * * @See: midgard_query_builder_add_constraint() * * Returns: %TRUE if properties' names are valid, %FALSE otherwise */ gboolean midgard_query_builder_add_constraint_with_property( MidgardQueryBuilder *builder, const gchar *property_a, const gchar *op, const gchar *property_b) { g_assert(builder != NULL); g_assert(property_a != NULL); g_assert(op != NULL); g_assert(property_b != NULL); MidgardDBObjectClass *klass = MIDGARD_DBOBJECT_CLASS(g_type_class_peek(builder->priv->type)); MidgardCoreQueryConstraint *constraint = midgard_core_query_constraint_new(); midgard_core_query_constraint_set_builder(constraint, builder); midgard_core_query_constraint_set_class(constraint, klass); if(!midgard_core_query_constraint_parse_property(&constraint, klass, property_a)) return FALSE; constraint->priv->current = constraint->priv->prop_right; if(!midgard_core_query_constraint_parse_property(&constraint, klass, property_b)) return FALSE; constraint->priv->condition_operator = g_strdup(op); midgard_core_query_constraint_build_condition(constraint); midgard_core_qb_add_table(builder, constraint->priv->prop_left->table); midgard_core_qb_add_table(builder, constraint->priv->prop_right->table); if(builder->priv->grouping_ref > 0) { MidgardGroupConstraint *group = builder->priv->group_constraint; midgard_group_constraint_add_constraint(group, constraint); return TRUE; } else { midgard_core_qb_add_constraint(builder, constraint); } return TRUE; }
static const gchar *_collector_find_class_property( MidgardCollector *self, const gchar *propname) { const gchar *table_field = midgard_core_class_get_property_tablefield( MIDGARD_DBOBJECT_CLASS(self->priv->klass), propname); /* Let's try metadata class */ if(table_field == NULL) { MidgardMetadataClass *mklass = (MidgardMetadataClass*) g_type_class_peek(g_type_from_name("MidgardMetadata")); GParamSpec *pspec = g_object_class_find_property (G_OBJECT_CLASS (mklass), propname); /* We do not need table.col alias, so dummy empty string is fine in this case */ if (pspec) return ""; } return table_field; }
static void __get_property_attribute (xmlNode *node, gchar **property_string, gchar **target_name, MgdSchemaPropertyAttr **prop_attr, MidgardDBObjectClass *klass) { *target_name = property_string[1]; if (property_string[2] != NULL && !g_str_equal (*target_name, "metadata")) { __view_error (node, "%s not allowed in view configuration", target_name); return; } /* Check metadata */ if (property_string[2] != NULL && g_str_equal (*target_name, "metadata")) { if (!MGD_DBCLASS_METADATA_CLASS (klass)) { __view_error (node, "No metadata registered for %s class", G_OBJECT_CLASS_NAME (klass)); return; } *target_name = property_string[2]; *prop_attr = g_hash_table_lookup (MIDGARD_DBOBJECT_CLASS (MGD_DBCLASS_METADATA_CLASS (klass))->dbpriv->storage_data->prophash, *target_name); if (!*prop_attr) __view_error (node, "%s not found. Not registered for %s.metadata ?", *target_name, property_string[0]); } /* Fallback to custom properties, metadata class doesn't exist in MgdSchema scope */ if (!*prop_attr) { *prop_attr = g_hash_table_lookup (klass->dbpriv->storage_data->prophash, *target_name); if (!*prop_attr) __view_error(node, "%s not found. Not registered for %s ?", *target_name, property_string[0]); if ((*prop_attr)->is_private) __view_error (node, "Private property %s.%s can not be added to view.", G_OBJECT_CLASS_NAME (G_OBJECT_CLASS (klass)), (*prop_attr)->name); } }
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); }
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 __set_schema_property_attr( MidgardQueryBuilder *builder, MidgardDBObjectClass **klass, MidgardCoreQueryConstraint **constraint, const gchar *name, gboolean do_link) { MgdSchemaPropertyAttr *attr = NULL; const gchar *target_property = NULL; const gchar *link_property = NULL; /* Set klass and property so later we use this info when * gvalue typecasting should be done */ (*constraint)->priv->klass = G_OBJECT_CLASS(*klass); (*constraint)->priv->propname = name; /* Reserved properties */ /* METADATA */ if (g_str_equal("metadata", name)) { *klass = g_type_class_peek(MIDGARD_TYPE_METADATA); return TRUE; } /* ATTACHMENT */ if (g_str_equal(_RESERVED_BLOB_NAME, name)) { if (builder && !builder->priv->blob_join_exists) { __join_reference(builder, (const gchar *)(*constraint)->priv->current->table, _RESERVED_BLOB_TABLE); builder->priv->blob_join_exists = TRUE; } *klass = g_type_class_peek(g_type_from_name("midgard_attachment")); (*constraint)->priv->current->table = _RESERVED_BLOB_TABLE; return TRUE; } /* PARAMETER */ if (g_str_equal(_RESERVED_PARAM_NAME, name)) { if (builder && !builder->priv->param_join_exists) { __join_reference(builder, (const gchar *)(*constraint)->priv->current->table, _RESERVED_PARAM_TABLE); builder->priv->param_join_exists = TRUE; } *klass = g_type_class_peek(g_type_from_name("midgard_parameter")); (*constraint)->priv->current->table = _RESERVED_PARAM_TABLE; /* Select DISTINCT. * Constraints might be grouped with "OR" operator and duplicated * records can be returned explicitly */ if (builder) { builder->priv->select_distinct = TRUE; } return TRUE; } /* User defined properties */ GParamSpec *pspec = g_object_class_find_property(G_OBJECT_CLASS(*klass), name); if(!pspec) { g_warning("%s is not registered property of %s class", name, G_OBJECT_CLASS_NAME(*klass)); return FALSE; } /* Set klass and property so later we use this info when gvalue typecasting should be done */ (*constraint)->priv->klass = G_OBJECT_CLASS(*klass); (*constraint)->priv->propname = pspec->name; (*constraint)->priv->pspec = pspec; attr = midgard_core_class_get_property_attr (MIDGARD_DBOBJECT_CLASS(*klass), name); target_property = NULL; link_property = NULL; MidgardReflectionProperty *mrp = midgard_reflection_property_new (MIDGARD_DBOBJECT_CLASS (*klass)); if (midgard_reflection_property_is_link (mrp, name) && do_link) { const gchar *target_property = midgard_reflection_property_get_link_target(mrp, name); const gchar *link_klass = midgard_reflection_property_get_link_name(mrp, name); gboolean is_link = TRUE; if ((*constraint)->priv->current->link_target == NULL) { MidgardCoreQueryConstraintPrivate *mqcp = midgard_core_query_constraint_private_new(); mqcp->current->is_link = is_link; mqcp->current->link_target = target_property; mqcp->condition_operator = g_strdup("="); mqcp->prop_left->table = midgard_core_class_get_property_table (MIDGARD_DBOBJECT_CLASS(*klass), name); mqcp->prop_left->field = midgard_core_class_get_property_colname (MIDGARD_DBOBJECT_CLASS(*klass), name); MidgardObjectClass *lclass = g_type_class_peek (g_type_from_name(link_klass)); mqcp->prop_right->table = midgard_core_class_get_property_table (MIDGARD_DBOBJECT_CLASS(lclass), target_property); mqcp->prop_right->field = midgard_core_class_get_property_colname (MIDGARD_DBOBJECT_CLASS(lclass), target_property); GString *cond = g_string_new (""); g_string_append_printf (cond, "%s.%s %s %s.%s", mqcp->prop_left->table, mqcp->prop_left->field, mqcp->condition_operator, mqcp->prop_right->table, mqcp->prop_right->field); mqcp->condition = g_string_free (cond, FALSE); if (builder) { midgard_core_qb_add_table(builder, mqcp->prop_left->table); midgard_core_qb_add_table(builder, mqcp->prop_right->table); } if (builder) { if(!__add_join(&builder->priv->joins, mqcp)) { midgard_core_query_constraint_private_free(mqcp); } } } *klass = (MidgardDBObjectClass *) midgard_reflection_property_get_link_class(mrp, name); (*constraint)->priv->current->table = midgard_core_class_get_table(MIDGARD_DBOBJECT_CLASS(*klass)); g_object_unref(mrp); return TRUE; } g_object_unref(mrp); const gchar *table, *field; if (g_str_equal (name, "guid")) { table = midgard_core_class_get_table(MIDGARD_DBOBJECT_CLASS(*klass)); field = "guid"; } else { table = attr->table; field = attr->field; } if(table != NULL) (*constraint)->priv->current->table = table; (*constraint)->priv->current->field = field; return TRUE; }
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; }
gchar *midgard_query_builder_get_object_select( MidgardQueryBuilder *builder, guint select_type){ g_assert(builder != NULL); g_assert(builder->priv->type); MidgardObjectClass *klass = (MidgardObjectClass*) g_type_class_peek(builder->priv->type); const gchar *table = midgard_core_class_get_table(MIDGARD_DBOBJECT_CLASS(klass)); if (!table){ g_warning("Object '%s' has no table or storage defined!", g_type_name(builder->priv->type)); return NULL; } GString *select = g_string_new(""); /* We are getting only guids */ if(select_type == MQB_SELECT_GUID){ g_string_append(select, "COUNT(*) "); return g_string_free(select, FALSE); } /* guid hardcoded ( inherited from MidgardObjectClass ) * metadata properties hardcoded ( defined in midgard_metadata ) */ /* FIXME, move this to particular class implementation, so we can reuse MidgardDBObject derived class data only */ if (MIDGARD_IS_OBJECT_CLASS (klass)) g_string_append_printf(select, "%s.guid, ", table); if (MIDGARD_DBOBJECT_CLASS(klass)->dbpriv->has_metadata) { g_string_append_printf(select, "%s.metadata_creator, " "%s.metadata_created, " "%s.metadata_revisor, " "%s.metadata_revised, " "%s.metadata_revision, " "%s.metadata_locker, " "%s.metadata_locked, " "%s.metadata_approver, " "%s.metadata_approved, " "%s.metadata_authors, " "%s.metadata_owner, " "%s.metadata_schedule_start, " "%s.metadata_schedule_end, " "%s.metadata_hidden, " "%s.metadata_nav_noentry, " "%s.metadata_size, " "%s.metadata_published, " "%s.metadata_exported, " "%s.metadata_imported, " "%s.metadata_deleted, " "%s.metadata_score, " "%s.metadata_islocked, " "%s.metadata_isapproved " ", ", table, table, table, table, table, table, table, table, table, table, table, table, table, table, table, table, table, table, table, table, table, table, table); /* TODO, Set select which suits better */ } if(builder->priv->schema->sql_select_full != NULL) { g_string_append_printf(select, " %s", builder->priv->schema->sql_select_full); } return g_string_free(select, FALSE); }
static void __get_view_constraints(xmlNode *node, MgdSchemaTypeAttr *type) { xmlNode *cur; for (cur = node->children; cur; cur = cur->next) { if (cur->type == XML_ELEMENT_NODE && g_str_equal(cur->name, "constraint")) { /* FIXME, add constraint to reserved words constants */ xmlChar *property = xmlGetProp(cur, (const xmlChar *)"property"); if (!property || (property && *property == '\0')) __view_error(cur, "Can not add constraint with empty property", NULL); gchar **classprop = g_strsplit((gchar *)property, ":", 2); if (!classprop || classprop[0] == NULL || classprop[1] == NULL) { __view_error(cur, "Constraint property misconfigured", NULL); return; } MidgardDBObjectClass *klass = MIDGARD_DBOBJECT_CLASS(MIDGARD_OBJECT_GET_CLASS_BY_NAME((const gchar *)classprop[0])); if (!klass) __view_error(cur, "Class %s not registered", classprop[0]); MidgardCoreQueryConstraint *constraint = midgard_core_query_constraint_new(); if (!midgard_core_query_constraint_parse_property(&constraint, klass, classprop[1])) __view_error(cur, "Can not parse %s constraint property", classprop[1]); g_strfreev(classprop); xmlFree(property); /* Add operator */ xmlChar *operator = xmlGetProp(cur, (const xmlChar *)"operator"); if (!operator || (operator && *operator == '\0')) __view_error(cur, "Can not add constraint with empty operator", NULL); if (!midgard_core_query_constraint_add_operator(constraint, (const gchar *)operator)) __view_error(cur, "Invalid operator", NULL); xmlFree(operator); /* Add value */ xmlChar *valtype = xmlGetProp(cur, (const xmlChar *)"value_type"); if (!valtype || (valtype && *valtype == '\0')) __view_error(cur, "Can not add constraint with empty value_type", NULL); GType vtype = midgard_core_schema_gtype_from_string((const gchar *)valtype); if (!vtype) __view_error(cur, "Invalid %s value_type", valtype); xmlFree(valtype); xmlChar *value = xmlGetProp(cur, (const xmlChar *)"value"); if (!value || (value && *value == '\0')) __view_error(cur, "Can not add constraint with empty value", NULL); /* Get value as string and convert to declared type */ GValue strval = {0, }; g_value_init(&strval, G_TYPE_STRING); g_value_set_string(&strval, (const gchar *)value); GValue val = {0, }; g_value_init(&val, vtype); g_value_transform((const GValue *) &strval, &val); midgard_core_query_constraint_add_value(constraint, &val); midgard_core_query_constraint_build_condition(constraint); type->constraints = g_slist_append(type->constraints, (gpointer) constraint); g_value_unset(&val); g_value_unset(&strval); xmlFree(value); } } }
gboolean midgard_core_query_constraint_parse_property (MidgardCoreQueryConstraint **constraint, MidgardDBObjectClass *klass, const gchar *name) { g_assert(name != NULL); if (!klass) klass = MIDGARD_DBOBJECT_CLASS((*constraint)->priv->klass); (*constraint)->priv->current->table = midgard_core_class_get_table(MIDGARD_DBOBJECT_CLASS(klass)); /* This is optional and might be set to NULL explicitly. We need to parse property for any class which needs this */ MidgardQueryBuilder *builder = (*constraint)->priv->builder; gchar **spltd = g_strsplit(name, ".", 0); guint i = 0; /* We can support max 3 tokens */ while(spltd[i] != NULL) i++; if(i == 1) { g_strfreev(spltd); /* FIXME , it should be done by some more generic function */ GParamSpec *pspec = g_object_class_find_property(G_OBJECT_CLASS(klass), name); if(!pspec) { g_warning("%s is not a member of %s", name, G_OBJECT_CLASS_NAME(klass)); return FALSE; } const gchar *stable = midgard_core_class_get_property_table( MIDGARD_DBOBJECT_CLASS(klass), name); (*constraint)->priv->pspec = pspec; (*constraint)->priv->current->field = midgard_core_class_get_property_colname( MIDGARD_DBOBJECT_CLASS(klass), name); (*constraint)->priv->current->table = stable; if (builder) midgard_core_qb_add_table(builder, stable); (*constraint)->priv->klass = G_OBJECT_CLASS(klass); (*constraint)->priv->propname = name; if(g_str_equal(name, "guid")) (*constraint)->priv->current->field = "guid"; return TRUE; } if(i > 3) { g_warning("Failed to parse '%s'. At most 3 tokens allowed", name); g_strfreev(spltd); return FALSE; } gboolean parsed = FALSE; gboolean do_link = TRUE; guint j = 0; while(spltd[j] != NULL) { if(j+1 == i) do_link = FALSE; parsed = __set_schema_property_attr (builder, &klass, constraint, (const gchar *) spltd[j], do_link); if(!parsed) { g_strfreev(spltd); return FALSE; } j++; } g_strfreev(spltd); return TRUE; }
static void _midgard_workspace_class_init( gpointer g_class, gpointer g_class_data) { GObjectClass *gobject_class = G_OBJECT_CLASS (g_class); MidgardWorkspaceClass *klass = MIDGARD_WORKSPACE_CLASS (g_class); __parent_class = g_type_class_peek_parent (g_class); gobject_class->constructor = _midgard_workspace_constructor; gobject_class->dispose = _midgard_workspace_dispose; gobject_class->finalize = _midgard_workspace_finalize; gobject_class->set_property = _midgard_workspace_set_property; gobject_class->get_property = _midgard_workspace_get_property; /* PROPERTIES */ MgdSchemaPropertyAttr *prop_attr; MgdSchemaTypeAttr *type_attr = midgard_core_schema_type_attr_new(); GParamSpec *pspec; const gchar *property_name; /* parent workspace */ property_name = "parent_workspace"; pspec = g_param_spec_object (property_name, "Parent workspace", "", MIDGARD_TYPE_WORKSPACE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (gobject_class, PROPERTY_PARENT_WS, pspec); /* id */ property_name = "id"; pspec = g_param_spec_uint (property_name, "Local storage id which identifies workspace", "", 0, G_MAXUINT32, 0, G_PARAM_READABLE); g_object_class_install_property (gobject_class, PROPERTY_ID, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_UINT; prop_attr->field = g_strdup(property_name); prop_attr->table = g_strdup(MGD_WORKSPACE_TABLE); prop_attr->tablefield = g_strjoin(".", MGD_WORKSPACE_TABLE, property_name, NULL); /* Set id property and field as Primary Key */ prop_attr->primaryfield = g_strdup (property_name); prop_attr->is_primary = TRUE; type_attr->primary = g_strdup (property_name); type_attr->primaryfield = g_strdup (property_name); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)property_name), prop_attr); type_attr->_properties_list = g_slist_append (type_attr->_properties_list, (gpointer) property_name); /* up */ property_name = "up"; pspec = g_param_spec_uint (property_name, "Local storage id which identifies up workspace", "", 0, G_MAXUINT32, 0, G_PARAM_READABLE); g_object_class_install_property (gobject_class, PROPERTY_UP, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_UINT; prop_attr->field = g_strdup(property_name); prop_attr->table = g_strdup(MGD_WORKSPACE_TABLE); prop_attr->tablefield = g_strjoin(".", MGD_WORKSPACE_TABLE, property_name, NULL); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)property_name), prop_attr); type_attr->_properties_list = g_slist_append (type_attr->_properties_list, (gpointer) property_name); /* guid */ property_name = "guid"; pspec = g_param_spec_string (property_name, "Guid which identifies workspace object.", "", "", G_PARAM_READABLE); g_object_class_install_property (gobject_class, PROPERTY_GUID, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_GUID; prop_attr->field = g_strdup (property_name); prop_attr->table = g_strdup (MGD_WORKSPACE_TABLE); prop_attr->tablefield = g_strjoin (".", MGD_WORKSPACE_TABLE, property_name, NULL); g_hash_table_insert (type_attr->prophash, g_strdup((gchar *)property_name), prop_attr); type_attr->_properties_list = g_slist_append (type_attr->_properties_list, (gpointer) property_name); /* path */ property_name = "path"; pspec = g_param_spec_string (property_name, "A path workspace is at", "", "", G_PARAM_READABLE); g_object_class_install_property (gobject_class, PROPERTY_PATH, pspec); /* name */ property_name = "name"; pspec = g_param_spec_string (property_name, "WorkspaceStorage name", "", "", G_PARAM_READWRITE); g_object_class_install_property (gobject_class, PROPERTY_NAME, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_STRING; prop_attr->field = g_strdup (property_name); prop_attr->table = g_strdup (MGD_WORKSPACE_TABLE); prop_attr->tablefield = g_strjoin (".", MGD_WORKSPACE_TABLE, property_name, NULL); g_hash_table_insert (type_attr->prophash, g_strdup((gchar *)property_name), prop_attr); type_attr->_properties_list = g_slist_append (type_attr->_properties_list, (gpointer )property_name); MIDGARD_DBOBJECT_CLASS (klass)->dbpriv = midgard_core_dbobject_private_new (); MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->storage_data = type_attr; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->storage_data->table = g_strdup(MGD_WORKSPACE_TABLE); MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->storage_data->tables = g_strdup(MGD_WORKSPACE_TABLE); MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->has_metadata = FALSE; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->create_storage = midgard_core_query_create_class_storage; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->update_storage = midgard_core_query_update_class_storage; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->storage_exists = _workspace_storage_exists; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->delete_storage = _workspace_storage_delete; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->get_statement_insert = MIDGARD_DBOBJECT_CLASS (__parent_class)->dbpriv->get_statement_insert; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->get_statement_insert_params = MIDGARD_DBOBJECT_CLASS (__parent_class)->dbpriv->get_statement_insert_params; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->get_statement_update = MIDGARD_DBOBJECT_CLASS (__parent_class)->dbpriv->get_statement_update; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->get_statement_update_params = MIDGARD_DBOBJECT_CLASS (__parent_class)->dbpriv->get_statement_update_params; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->add_fields_to_select_statement = MIDGARD_DBOBJECT_CLASS (__parent_class)->dbpriv->add_fields_to_select_statement; MIDGARD_DBOBJECT_CLASS (klass)->dbpriv->set_from_data_model = _set_from_data_model; }
static void __get_view_joins(xmlNode *node, MgdSchemaTypeAttr *type) { xmlNode *cur; gchar *property_name = NULL; MgdSchemaPropertyAttr *propright = NULL; MgdSchemaPropertyAttr *propleft = NULL; for (cur = node->children; cur; cur = cur->next) { if (cur->type == XML_ELEMENT_NODE && g_str_equal(cur->name, "join")) { /* FIXME, add join to reserved words constants */ property_name = NULL; propright = NULL; propleft = NULL; xmlChar *jointype = xmlGetProp(cur, (const xmlChar *)"type"); if (!jointype || (jointype && *jointype == '\0')) __view_error(cur, "Can not create join with empty type", NULL); if (!midgard_core_xml_attribute_is_allowed(__allowed_joins, jointype)) __view_error(cur, "%s join type is not allowed", jointype); xmlChar *classname = xmlGetProp(cur, (const xmlChar *)"class"); xmlChar *table = NULL; if (!classname || (classname && *classname == '\0')) { table = xmlGetProp(cur, (const xmlChar *) TYPE_RW_TABLE); if (!table) __view_error(cur, "Can not create join. Empty, not defined class or table", NULL); } MidgardDBObjectClass *klass = NULL; MidgardDBObjectClass *joinklass = NULL; if (classname) joinklass = MIDGARD_DBOBJECT_CLASS(MIDGARD_OBJECT_GET_CLASS_BY_NAME((const gchar *)classname)); if (!joinklass) { g_warning ("%s is not registered in GType system", classname); __view_error (cur, "Invalid classname for defined join"); return; } gchar *left = midgard_core_xml_get_child_attribute_content_by_name(cur, "condition", "left"); if (!left) __view_error(cur, "Condition left is missing", NULL); gchar *right = midgard_core_xml_get_child_attribute_content_by_name(cur, "condition", "right"); if (!right) __view_error(cur, "Condition right is missing", NULL); /* Get left property attribute */ gchar **classprop = g_strsplit_set(left, ":.", -1); if (!classprop || classprop[0] == NULL || classprop[1] == NULL) { __view_error(cur, "Condition left problem", NULL); return; } klass = MIDGARD_DBOBJECT_CLASS(MIDGARD_OBJECT_GET_CLASS_BY_NAME((const gchar *)classprop[0])); if (!klass) { __view_error(cur, "Class %s not registered", classprop[0]); return; } MgdSchemaPropertyAttr *propleft = g_hash_table_lookup(klass->dbpriv->storage_data->prophash, classprop[1]); if (!propleft) __view_error(cur, "Property %s not registered for %s", classprop[1], classprop[0]); /* __get_property_attribute (cur, classprop, &property_name, &propleft, klass); */ g_strfreev(classprop); /* Get right property attribute */ classprop = g_strsplit_set(right, ":.", -1); if (!classprop || classprop[0] == NULL || classprop[1] == NULL) { __view_error(cur, "Condition right problem", NULL); return; } klass = MIDGARD_DBOBJECT_CLASS(MIDGARD_OBJECT_GET_CLASS_BY_NAME((const gchar *)classprop[0])); if (!klass) { __view_error(cur, "Class %s not registered", classprop[0]); return; } MgdSchemaPropertyAttr *propright = g_hash_table_lookup(klass->dbpriv->storage_data->prophash, classprop[1]); if (!propright) __view_error(cur, "Property %s not registered for %s", classprop[1], classprop[0]); /* __get_property_attribute (cur, classprop, &property_name, &propright, klass); */ g_strfreev(classprop); MidgardDBJoin *mdbj = midgard_core_dbjoin_new(); mdbj->type = g_utf8_strup((const gchar *)jointype, strlen((gchar *)jointype)); /* configure table, if there's class, get it's table, in other case, get table directly */ if (classname) mdbj->table = g_strdup(midgard_core_class_get_table(joinklass)); else mdbj->table = g_strdup((gchar *)table); mdbj->left = propleft; mdbj->right = propright; g_free(left); g_free(right); type->joins = g_slist_append(type->joins, (gpointer) mdbj); xmlFree(jointype); xmlFree(classname); if (table) xmlFree(table); } } }
g_assert(domain != NULL); g_assert(value != NULL); MidgardCollector *self = (MidgardCollector *)g_object_new(MIDGARD_TYPE_COLLECTOR, NULL); self->priv->klass = MIDGARD_OBJECT_GET_CLASS_BY_NAME(typename); /* Initialize private QB instance and set domain as constraint */ self->priv->builder = midgard_query_builder_new(mgd, typename); midgard_query_builder_add_constraint(self->priv->builder, domain, "=", value); MidgardDBObjectClass *klass = MIDGARD_DBOBJECT_CLASS(self->priv->klass); MidgardCoreQueryConstraint *constraint = midgard_core_query_constraint_new(); midgard_core_query_constraint_set_builder(constraint, self->priv->builder); midgard_core_query_constraint_set_class(constraint, klass); if(!midgard_core_query_constraint_parse_property(&constraint, klass, domain)) { g_object_unref(constraint); /* FIXME */ if(value) { g_value_unset(value); g_free(value); }
static void __get_view_properties(xmlNode *node, MgdSchemaTypeAttr *type) { xmlNode *cur; MgdSchemaPropertyAttr *rprop_attr = NULL; gchar *property_name = NULL; for (cur = node->children; cur; cur = cur->next) { if (cur->type == XML_ELEMENT_NODE && g_str_equal(cur->name, "property")) { /* FIXME, add property to reserved words constants */ property_name = NULL; rprop_attr = NULL; xmlChar *name = xmlGetProp(cur, (const xmlChar *)TYPE_RW_NAME); if (!name || (name && *name == '\0')) __view_error(cur, "Can not register view with empty property", NULL); xmlChar *use_prop = xmlGetProp(cur, (const xmlChar *) "use"); /* FIXME, use reserved word */ if (!use_prop || (use_prop && *use_prop == '\0')) __view_error(cur, "Referenced class:property can not be empty", NULL); gchar **rprop = g_strsplit_set ((const gchar *)use_prop, ":.", -1); xmlFree (use_prop); if (!rprop || rprop[0] == NULL || rprop[1] == NULL) { __view_error(cur, "Referenced property can not be empty", NULL); return; } MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS_BY_NAME(rprop[0]); if (!klass) __view_error (cur, "Defined '%s' class is not registered as midagrd_object derived one", rprop[0]); const gchar *table = midgard_core_class_get_table (MIDGARD_DBOBJECT_CLASS (klass)); if (table == NULL) __view_error (cur, "Can not create proper view. Defined '%s' class has NULL storage", rprop[0]); __get_property_attribute (cur, rprop, &property_name, &rprop_attr, MIDGARD_DBOBJECT_CLASS (klass)); midgard_core_schema_type_property_copy(rprop_attr, type); /* TODO, refactor with some usable TypeAttr related API */ /* Create property attributes copy using original property. Then change name. */ MgdSchemaPropertyAttr *prop_attr = g_hash_table_lookup(type->prophash, property_name); if (!prop_attr) g_warning("Can not find %s.%s in newly registered view", type->name, name); if (prop_attr) { g_free((gchar *)prop_attr->name); prop_attr->name = g_strdup((gchar *)name); /* Free old key and remove new one in hash table */ g_hash_table_remove(type->prophash, (gconstpointer) rprop[1]); gchar *property_name = g_strdup ((gchar *)name); g_hash_table_insert(type->prophash, property_name, prop_attr); /* FIXME * Workaround for properties not being registered in the same order as defined * in view xml file */ type->_properties_list = g_slist_append (type->_properties_list, property_name); } g_strfreev(rprop); xmlFree(name); } } }
/* Create GdaSqlSelectField for every property registered for the class. */ void _add_fields_to_select_statement (MidgardDBObjectClass *klass, MidgardConnection *mgd, GdaSqlStatementSelect *select, const gchar *table_name) { guint n_prop; guint i; GdaSqlSelectField *select_field; GdaSqlExpr *expr; GValue *val; gchar *table_field; GdaConnection *cnc = mgd->priv->connection; GParamSpec **pspecs = g_object_class_list_properties (G_OBJECT_CLASS (klass), &n_prop); if (!pspecs) return; const gchar *property_table = NULL; for (i = 0; i < n_prop; i++) { const gchar *property = pspecs[i]->name; const gchar *property_field = midgard_core_class_get_property_colname (klass, property); property_table = midgard_core_class_get_property_table (klass, property); if (property_table && table_name) property_table = table_name; /* Ignore properties with NULL storage and those of object type */ if (!property_table || pspecs[i]->value_type == G_TYPE_OBJECT) continue; select_field = gda_sql_select_field_new (GDA_SQL_ANY_PART (select)); /*select_field->field_name = g_strdup (property_field); select_field->table_name = g_strdup (property_table);*/ select_field->as = gda_connection_quote_sql_identifier (cnc, property); select->expr_list = g_slist_append (select->expr_list, select_field); expr = gda_sql_expr_new (GDA_SQL_ANY_PART (select_field)); val = g_new0 (GValue, 1); g_value_init (val, G_TYPE_STRING); gchar *q_table = gda_connection_quote_sql_identifier (cnc, property_table); gchar *q_field = gda_connection_quote_sql_identifier (cnc, property_field); table_field = g_strconcat (q_table, ".", q_field, NULL); g_value_set_string (val, table_field); g_free (q_table); g_free (q_field); g_free (table_field); expr->value = val; select_field->expr = expr; } g_free (pspecs); if (!klass->dbpriv->has_metadata) return; /* Check if metadata provides own method to add fields. If not, use given class storage. */ if (MIDGARD_IS_OBJECT_CLASS (klass)) { MidgardMetadataClass *mklass = MGD_DBCLASS_METADATA_CLASS (klass); if (!mklass) return; if (MIDGARD_DBOBJECT_CLASS (mklass)->dbpriv->add_fields_to_select_statement) { MIDGARD_DBOBJECT_CLASS (mklass)->dbpriv->add_fields_to_select_statement (MIDGARD_DBOBJECT_CLASS (mklass), mgd, select, table_name); return; } const gchar *table = midgard_core_class_get_table (klass); if (table_name) table = table_name; /* TODO, Once we stabilize use case, refactor this below to minimize code usage */ GParamSpec **pspecs = g_object_class_list_properties (G_OBJECT_CLASS (mklass), &n_prop); if (!pspecs) return; for (i = 0; i < n_prop; i++) { const gchar *property = pspecs[i]->name; const gchar *property_field = midgard_core_class_get_property_colname (MIDGARD_DBOBJECT_CLASS (mklass), property); if (pspecs[i]->value_type == G_TYPE_OBJECT || !property_field) continue; select_field = gda_sql_select_field_new (GDA_SQL_ANY_PART (select)); /*select_field->field_name = g_strdup (property_field); select_field->table_name = g_strdup (table);*/ select_field->as = g_strconcat ("metadata_", property, NULL); select->expr_list = g_slist_append (select->expr_list, select_field); expr = gda_sql_expr_new (GDA_SQL_ANY_PART (select_field)); val = g_new0 (GValue, 1); g_value_init (val, G_TYPE_STRING); table_field = g_strconcat (table, ".", property_field, NULL); g_value_set_string (val, table_field); g_free (table_field); expr->value = val; select_field->expr = expr; } g_free (pspecs); } return; }
/** * midgard_replicator_export_by_guid: * @mgd: #MidgardConnection instance * @guid: guid which identifies object to be exported * * Marks object's storage record as exported. * * Cases to return %FALSE: * <itemizedlist> * <listitem><para> * Given guid is NULL or empty string (MGD_ERR_INVALID_PROPERTY_VALUE) * </para></listitem> * <listitem><para> * Object identified by given guid doesn't exist (MGD_ERR_NOT_EXISTS) * </para></listitem> * <listitem><para> * Object identified by given guid is purged (MGD_ERR_OBJECT_PURGED) * </para></listitem> * <listitem><para> * Internal storage error (MGD_ERR_INTERNAL) * </para></listitem> * </itemizedlist> * * Returns: %TRUE on success, %FALSE otherwise */ gboolean midgard_replicator_export_by_guid (MidgardConnection *mgd, const gchar *guid) { g_return_val_if_fail (mgd != NULL, FALSE); if(guid == NULL || (guid && (*guid == '\0'))) { MIDGARD_ERRNO_SET_STRING (mgd, MGD_ERR_INVALID_PROPERTY_VALUE, "Empty or NULL guid given"); return FALSE; } MIDGARD_ERRNO_SET(mgd, MGD_ERR_OK); MidgardDBObject *repligard = NULL; GError *error = NULL; GValue gval = {0, }; g_value_init (&gval, G_TYPE_STRING); g_value_set_string (&gval, guid); midgard_core_query_get_object (mgd, g_type_name (MIDGARD_TYPE_REPLIGARD), &repligard, FALSE, &error, "guid", &gval, NULL); g_value_unset (&gval); if (error) { MIDGARD_ERRNO_SET_STRING (mgd, error->code, "%s", error->message); g_clear_error (&error); if (repligard) g_object_unref (G_OBJECT (repligard)); return FALSE; } guint action; gchar *classname; g_object_get (repligard, "action", &action, "type", &classname, NULL); g_object_unref (repligard); MidgardObjectClass *klass = MIDGARD_OBJECT_GET_CLASS_BY_NAME(classname); if(klass == NULL) { g_warning("Failed to get class pointer for '%s', an object identified with '%s'", classname, guid); MIDGARD_ERRNO_SET(mgd, MGD_ERR_INTERNAL); g_free (classname); return FALSE; } g_free (classname); const gchar *table = midgard_core_class_get_table(MIDGARD_DBOBJECT_CLASS(klass)); GValue tval = {0, }; gchar *timeupdated; gint qr; GString *sql = NULL; switch(action) { case MGD_OBJECT_ACTION_PURGE: MIDGARD_ERRNO_SET(mgd, MGD_ERR_OBJECT_PURGED); return FALSE; break; default: sql = g_string_new ("UPDATE "); g_string_append_printf(sql, "%s SET ", table); midgard_timestamp_new_current (&tval); timeupdated = midgard_timestamp_get_string_from_value (&tval); g_string_append_printf(sql, "metadata_exported='%s' WHERE guid = '%s' ", timeupdated, guid); qr = midgard_core_query_execute(mgd, sql->str, TRUE); g_string_free(sql, TRUE); g_value_unset (&tval); g_free(timeupdated); if (qr == 0) { MIDGARD_ERRNO_SET(mgd, MGD_ERR_INTERNAL); return FALSE; } return TRUE; break; } return FALSE; }
static void _midgard_query_select_validable_iface_validate (MidgardValidable *iface, GError **error) { g_return_if_fail (iface != NULL); MidgardQuerySelect *self = MIDGARD_QUERY_SELECT (iface); MIDGARD_QUERY_EXECUTOR (self)->priv->is_valid = FALSE; GError *err = NULL; MidgardQueryStorage *storage = MIDGARD_QUERY_EXECUTOR (self)->priv->storage; GObjectClass *klass = (GObjectClass *) storage->priv->klass; if (klass == NULL || (!G_IS_OBJECT_CLASS(klass))) { g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_TYPE_INVALID, "Invalid '%s' classname associated with QueryStorage", storage->priv->classname); return; } const gchar *table = midgard_core_class_get_table (MIDGARD_DBOBJECT_CLASS (klass)); /* Class table */ if (!table) { g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_LOCATION_INVALID, "No SQL table defined for '%s' class", G_OBJECT_CLASS_NAME (klass)); return; } /* Storage */ if (!storage) { g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_LOCATION_INVALID, "No QueryStorage associated with QuerySelect"); return; } if (storage->priv->klass && !storage->priv->klass->dbpriv->add_fields_to_select_statement) { g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_INTERNAL, "'%s' DBObjectClass doesn't provide select statement.", G_OBJECT_CLASS_NAME (storage->priv->klass)); return; } /* Limit */ if (MIDGARD_QUERY_EXECUTOR (self)->priv->limit == 0) { g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_VALUE_INVALID, "Invalid limit value (0). Expected > 0"); return; } /* Orders */ GSList *l = NULL; for (l = MIDGARD_QUERY_EXECUTOR (self)->priv->orders; l != NULL; l = l->next) { qso *_so = (qso*) l->data; gboolean asc = FALSE; gchar *lorder = g_ascii_strdown (_so->order_type, -1); if (g_str_equal (lorder, "asc")) { _so->asc = TRUE; } else if (g_str_equal (lorder, "desc")) { _so->asc = FALSE; } else { g_set_error (error, MIDGARD_VALIDATION_ERROR, MIDGARD_VALIDATION_ERROR_VALUE_INVALID, "Invalid order type '%s'. Expected ASC or DESC", _so->order_type); g_free (lorder); return; } g_free (lorder); } /* Gather all objects required for execution */ GSList *o_list = NULL; o_list = g_slist_prepend (o_list, storage); _get_all_constraints (self, NULL, &o_list); for (l = o_list; l != NULL; l = l->next) { if (!midgard_validable_is_valid (MIDGARD_VALIDABLE (l->data))) { midgard_validable_validate (MIDGARD_VALIDABLE (l->data), &err); if (err) { g_propagate_error (error, err); g_slist_free (o_list); return; } } } if (o_list) g_slist_free (o_list); MIDGARD_QUERY_EXECUTOR (self)->priv->is_valid = TRUE; return; }
/* Initialize class */ static void _metadata_class_init (gpointer g_class, gpointer g_class_data) { GObjectClass *gobject_class = G_OBJECT_CLASS (g_class); MidgardMetadataClass *klass = MIDGARD_METADATA_CLASS (g_class); GParamSpec *pspec; __parent_class = g_type_class_peek_parent (g_class); gobject_class->constructor = _metadata_constructor; gobject_class->set_property = _metadata_set_property; gobject_class->get_property = _metadata_get_property; gobject_class->dispose = _metadata_dispose; gobject_class->finalize = _metadata_object_finalize; MgdSchemaPropertyAttr *prop_attr; MgdSchemaTypeAttr *type_attr = midgard_core_schema_type_attr_new(); /* Register properties */ /* creator */ pspec = g_param_spec_string ("creator", "metadata_creator", "Guid of the person who created object's record", NULL /* We can set midgard admin */, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_CREATOR, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_GUID; prop_attr->field = g_strdup("metadata_creator"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("creator"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"creator"), prop_attr); /* created */ pspec = g_param_spec_boxed ("created", "metadata_created", "ISO datetime when object's record has been created", MGD_TYPE_TIMESTAMP, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_CREATED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_created"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("created"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"created"), prop_attr); /* revisor */ pspec = g_param_spec_string ("revisor", "metadata_revisor", "Guid of the person who revised object's record", NULL, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_REVISOR, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_GUID; prop_attr->field = g_strdup("metadata_revisor"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("revisor"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"revisor"), prop_attr); /* revised */ pspec = g_param_spec_boxed ("revised", "metadata_revised", "ISO datetime when object's record has been revised", MIDGARD_TYPE_TIMESTAMP, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_REVISED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_revised"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("revised"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"revised"), prop_attr); /* revision */ pspec = g_param_spec_uint ("revision", "metadata_revision", "Object's record revision number", 0, G_MAXUINT32, 0, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_REVISION, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_UINT; prop_attr->field = g_strdup("metadata_revision"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("revision"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"revision"), prop_attr); /* locker */ pspec = g_param_spec_string ("locker", "metadata_locker", "Guid of the person who (un)locked object's record", NULL, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_LOCKER, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_GUID; prop_attr->field = g_strdup("metadata_locker"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("locker"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"locker"), prop_attr); /* locked */ pspec = g_param_spec_boxed ("locked", "metadata_locked", "ISO datetime when object's record has been (un)locked", MGD_TYPE_TIMESTAMP, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_LOCKED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_locked"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("locked"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"locked"), prop_attr); /* approver */ pspec = g_param_spec_string ("approver", "metadata_approver", "Guid of the person who (un)approved object's record", NULL, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_APPROVER, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_GUID; prop_attr->field = g_strdup("metadata_approver"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("approver"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"approver"), prop_attr); /* approved */ pspec = g_param_spec_boxed ("approved", "metadata_approved", "ISO datetime when object's record has been (un)approved", MGD_TYPE_TIMESTAMP, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_APPROVED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_approved"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("approved"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"approved"), prop_attr); /* authors */ pspec = g_param_spec_string ("authors", "metadata_authors", "The person who is an author.", "", G_PARAM_READWRITE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_AUTHORS, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_STRING; prop_attr->field = g_strdup("metadata_authors"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("authors"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"authors"), prop_attr); /* owner */ pspec = g_param_spec_string ("owner", "metadata_owner", "Group's guid which is an owner of the object", "", G_PARAM_READWRITE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_OWNER, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_GUID; prop_attr->field = g_strdup("metadata_owner"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("owner"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"owner"), prop_attr); /* schedulestart */ pspec = g_param_spec_boxed ("schedulestart", "metadata_schedule_start", "ISO datetime when publication time starts.", MGD_TYPE_TIMESTAMP, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_SCHEDULE_START, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_schedule_start"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("schedulestart"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"schedulestart"), prop_attr); /* scheduleend */ pspec = g_param_spec_boxed ("scheduleend", "metadata_schedule_end", "ISO datetime when publication time ends.", MGD_TYPE_TIMESTAMP, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_SCHEDULE_END, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_schedule_end"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("scheduleend"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"scheduleend"), prop_attr); /* hidden */ pspec = g_param_spec_boolean ("hidden", "metadata_hidden", "Whether object should be hidden or not.", FALSE, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_HIDDEN, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_BOOLEAN; prop_attr->field = g_strdup("metadata_hidden"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("hidden"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"hidden"), prop_attr); /* nav no entry */ pspec = g_param_spec_boolean ("navnoentry", "metadata_nav_noentry", "Whether object is part of navigation (e.g. menu).", FALSE, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_NAV_NOENTRY, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_BOOLEAN; prop_attr->field = g_strdup("metadata_nav_noentry"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("navnoentry"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"navnoentry"), prop_attr); /* size */ pspec = g_param_spec_uint ("size", "metadata_size", "Object's size in bytes", 0, G_MAXUINT32, 0, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_SIZE, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_UINT; prop_attr->field = g_strdup("metadata_size"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("size"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"size"), prop_attr); /* published */ pspec = g_param_spec_boxed ("published", "metadata_published", "ISO datetime when object should be published (by default it's created time)", MGD_TYPE_TIMESTAMP, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_PUBLISHED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_published"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("published"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"published"), prop_attr); /* score */ pspec = g_param_spec_int ("score", "metadata_score", "Object's record score", G_MININT32, G_MAXINT32, 0, G_PARAM_READWRITE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_SCORE, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_INT; prop_attr->field = g_strdup("metadata_score"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("score"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"score"), prop_attr); /* exported */ pspec = g_param_spec_boxed ("exported", "metadata_exported", "Whether object has been exported or not.", MGD_TYPE_TIMESTAMP, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_EXPORTED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_exported"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("exported"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"exported"), prop_attr); /* imported */ pspec = g_param_spec_boxed ("imported", "metadata_imported", "Whether object has been imported or not.", MGD_TYPE_TIMESTAMP, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_IMPORTED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_TIMESTAMP; prop_attr->field = g_strdup("metadata_imported"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("imported"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"imported"), prop_attr); /* deleted */ pspec = g_param_spec_boolean ("deleted", "metadata_deleted", "Whether object is deleted or not.", FALSE, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_DELETED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_BOOLEAN; prop_attr->field = g_strdup("metadata_deleted"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("deleted"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"deleted"), prop_attr); /* isapproved */ pspec = g_param_spec_boolean ("isapproved", "metadata_isapproved", "Whether object is approved or not.", FALSE, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_ISAPPROVED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_BOOLEAN; prop_attr->field = g_strdup("metadata_isapproved"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("isapproved"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"isapproved"), prop_attr); /* islocked */ pspec = g_param_spec_boolean ("islocked", "metadata_islocked", "Whether object is locked or unlocked.", FALSE, G_PARAM_READABLE); g_object_class_install_property (gobject_class, MIDGARD_METADATA_ISLOCKED, pspec); prop_attr = midgard_core_schema_type_property_attr_new(); prop_attr->gtype = MGD_TYPE_BOOLEAN; prop_attr->field = g_strdup("metadata_islocked"); prop_attr->table = NULL; prop_attr->tablefield = NULL; prop_attr->name = g_strdup ("islocked"); g_hash_table_insert(type_attr->prophash, g_strdup((gchar *)"islocked"), prop_attr); /* Initialize private member */ MidgardDBObjectClass *dbklass = MIDGARD_DBOBJECT_CLASS (klass); dbklass->dbpriv = g_new(MidgardDBObjectPrivate, 1); dbklass->dbpriv->storage_data = type_attr; dbklass->dbpriv->set_from_xml_node = __set_from_xml_node; dbklass->dbpriv->add_fields_to_select_statement = NULL; dbklass->dbpriv->has_metadata = FALSE; dbklass->dbpriv->get_property = _midgard_metadata_dbpriv_get_property; dbklass->dbpriv->set_property = midgard_core_metadata_dbpriv_set_property; dbklass->dbpriv->set_from_data_model = _midgard_metadata_set_from_data_model; }