static void __join_reference(MidgardQueryBuilder *builder, const gchar *src_table, const gchar *ref_table)
{
	/* Join guid and parent_guid */
	MidgardCoreQueryConstraint *jc = midgard_core_query_constraint_new();
	GString *jstr = g_string_new("");
	g_string_append_printf(jstr,"%s.parent_guid = %s.guid",
			ref_table, src_table);
	jc->priv->condition = g_strdup(jstr->str);
	g_string_free(jstr, TRUE);
	
	midgard_core_qb_add_constraint(builder,jc);
	
	/* limit to records which are not deleted */
	MidgardCoreQueryConstraint *dc = midgard_core_query_constraint_new();
	GString *dstr = g_string_new("");
	g_string_append_printf(dstr,"%s.metadata_deleted = 0", ref_table);
	dc->priv->condition = g_string_free(dstr, FALSE);
	
	midgard_core_qb_add_constraint(builder,dc);
	
	return;
}
Пример #2
0
/**
 * 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;
}
Пример #3
0
/**
 * 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;
}