MidgardQueryBuilder

MidgardQueryBuilder — Database object query

Synopsis

#include <midgard/midgard.h>

struct              MidgardQueryBuilder;
                    MidgardQueryBuilderPrivate;
typedef             MidgardQueryBuilderClass;
MidgardQueryBuilder * midgard_query_builder_new         (MidgardConnection *mgd,
                                                         const gchar *classname);
MidgardQueryBuilder * midgard_query_builder_create_builder
                                                        (MidgardConnection *mgd,
                                                         const gchar *classname);
gboolean            midgard_query_builder_add_constraint
                                                        (MidgardQueryBuilder *builder,
                                                         const gchar *name,
                                                         const gchar *op,
                                                         const GValue *value);
gboolean            midgard_query_builder_add_constraint_with_property
                                                        (MidgardQueryBuilder *builder,
                                                         const gchar *property_a,
                                                         const gchar *op,
                                                         const gchar *property_b);
gboolean            midgard_query_builder_begin_group   (MidgardQueryBuilder *builder,
                                                         const gchar *type);
gboolean            midgard_query_builder_end_group     (MidgardQueryBuilder *builder);
gboolean            midgard_query_builder_add_order     (MidgardQueryBuilder *builder,
                                                         const gchar *name,
                                                         const gchar *dir);
void                midgard_query_builder_set_offset    (MidgardQueryBuilder *builder,
                                                         guint offset);
void                midgard_query_builder_set_limit     (MidgardQueryBuilder *builder,
                                                         guint limit);
GObject **          midgard_query_builder_execute       (MidgardQueryBuilder *builder,
                                                         guint *n_objects);
guint               midgard_query_builder_count         (MidgardQueryBuilder *builder);
const gchar *       midgard_query_builder_get_type_name (MidgardQueryBuilder *builder);
void                midgard_query_builder_include_deleted
                                                        (MidgardQueryBuilder *builder);

Object Hierarchy

  GObject
   +----MidgardQueryBuilder
         +----MidgardCollector

Signals

  "execution-end"                                  : No Hooks
  "execution-start"                                : No Hooks

Description

The MidgardQueryBuilder allows an application to construct and execute queries against any database, which Midgard is connected to.

Main MidgardQueryBuilder conveniences:

  • It doesn't require any SQL

  • Object properties are used as query constraints

  • Objects' array is returned instead of raw records

The main steps of using the query builder are:

Each query is represented by an instance of the MidgardQueryBuilderClass class. The MidgardQueryBuilder methods can be used to manipulate the queries.

Details

struct MidgardQueryBuilder

struct MidgardQueryBuilder;


MidgardQueryBuilderPrivate

typedef struct {
	GSList *constraints;
	GSList *groups;
	gboolean is_grouping;
	guint grouping_ref;
	MidgardGroupConstraint *group_constraint;
	GSList *joins;
	GHashTable *tables;
	GSList *orders;
	GValue *value;

	/* constants */
	MidgardConnection *mgd;
	MgdSchemaTypeAttr *schema;
	GType type;

	guint offset;
	guint limit;
	gboolean include_deleted;
	gboolean select_distinct;
	gint error;

	/* references for reserved joins */
	gboolean param_join_exists;
	gboolean blob_join_exists;
} MidgardQueryBuilderPrivate;


MidgardQueryBuilderClass

typedef struct MidgardQueryBuilderClass MidgardQueryBuilderClass;


midgard_query_builder_new ()

MidgardQueryBuilder * midgard_query_builder_new         (MidgardConnection *mgd,
                                                         const gchar *classname);

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.

midgard_query_builder_create_builder ()

MidgardQueryBuilder * midgard_query_builder_create_builder
                                                        (MidgardConnection *mgd,
                                                         const gchar *classname);

Static constructor. Invokes midgard_query_builder_new(). This function is added for language bindings, in which, that function can not be invoked explicitly.

Returns :

new MidgardQueryBuilder instance. [transfer full]

Since 10.05.1


midgard_query_builder_add_constraint ()

gboolean            midgard_query_builder_add_constraint
                                                        (MidgardQueryBuilder *builder,
                                                         const gchar *name,
                                                         const gchar *op,
                                                         const GValue *value);

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.

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 1. 


GValue value = {0, };
g_value_init(&value, G_TYPE_STRING);
g_value_set_string(&value, "smith");

midgard_query_builder_add_constraint(builder, "lastname", "=", &value);


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.

  • 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 2. 

    
    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);
    
    


  • 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 3. 

    
    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);
    
    


The comparison operator is a string representation of the requested comparison. Available operators are =, <>, <, >, <=, >=, LIKE, NOT LIKE, IN, INTREE.

The given value is copied and converted into the property type before comparison.

builder :

MidgardQueryBuilder instance

name :

property name used for this constraint

op :

comparison operator

value :

value used in comparison

Returns :

TRUE if constraint is valid, FALSE otherwise

midgard_query_builder_add_constraint_with_property ()

gboolean            midgard_query_builder_add_constraint_with_property
                                                        (MidgardQueryBuilder *builder,
                                                         const gchar *property_a,
                                                         const gchar *op,
                                                         const gchar *property_b);

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 4. 


midgard_query_builder_add_constraint_with_property(builder, "metadata.revised", ">", "metadata.published");


See: midgard_query_builder_add_constraint()

builder :

MidgardQueryBuilder instance

property_a :

property name

op :

comparison operator

property_b :

property name

Returns :

TRUE if properties' names are valid, FALSE otherwise

midgard_query_builder_begin_group ()

gboolean            midgard_query_builder_begin_group   (MidgardQueryBuilder *builder,
                                                         const gchar *type);

Starts a constraint group of the given type. A conjunctive constraint group type (AND) requires that all component constraints match the queried objects, while a disjunctive group type (OR) requires just one of the component constraints to match.

Allowed group type: 'AND' or 'OR'

builder :

MidgardQueryBuilder instance

type :

group type

Returns :

TRUE if the type is valid, FALSE otherwise

midgard_query_builder_end_group ()

gboolean            midgard_query_builder_end_group     (MidgardQueryBuilder *builder);

Closes the most recently opened constraint group. The client should ensure proper nesting by closing all constraint groups before the containing query is executed.

builder :

MidgardQueryBuilder instance

Returns :

TRUE if a constraint group was closed, or FALSE if no open constraint groups were found

midgard_query_builder_add_order ()

gboolean            midgard_query_builder_add_order     (MidgardQueryBuilder *builder,
                                                         const gchar *name,
                                                         const gchar *dir);

Adds an ordering constraint to the query. An ordering constraint consists of a property name and a sort direction. The objects returned by this query will be sorted by the given property in the given direction (ascending or descending). Multiple ordering constraints are applied in the order they were added.

Allowed sort directions: 'ASC' or 'DESC'

Property name pattern is described in midgard_query_builder_add_constraint()

builder :

MidgardQueryBuilder instance

name :

property name

dir :

sort direction

Returns :

TRUE if the ordering constraint is valid, FALSE otherwise

midgard_query_builder_set_offset ()

void                midgard_query_builder_set_offset    (MidgardQueryBuilder *builder,
                                                         guint offset);

Sets the start offset of the objects to return when the query is executed. The start offset is applied after all the matching objects have been identified and sorted according to the given ordering constraints. The first offset objects are skipped and only the remaining (if any) objects are returned to the client.

Setting a start offset is normally only reasonable when one or more ordering constraints are applied to the query. A start offset is usually accompanied by a limit setting.

See: midgard_query_builder_set_offset()

builder :

MidgardQueryBuilder instance

offset :

query offset

midgard_query_builder_set_limit ()

void                midgard_query_builder_set_limit     (MidgardQueryBuilder *builder,
                                                         guint limit);

Sets the maximum number of objects to return when the query is executed. A query will by default return all matching objects, but the limit setting can be used to restrict the potentially large number of returned objects. The limit is applied only after the matching objects have been identified and sorted and after the optional start offset has been applied.

Setting a limit on the number of returned objects is normally only reasonable when one or more ordering constraints and optionally an offset setting are applied to the query.

See: midgard_query_builder_set_offset()

builder :

MidgardQueryBuilder instance

limit :

query limit

midgard_query_builder_execute ()

GObject **          midgard_query_builder_execute       (MidgardQueryBuilder *builder,
                                                         guint *n_objects);

Executes the built query.

Objects in returned array are MidgardDBObject derived ones, and typecasted to base GObject. You can safely typecast them to the type, which MidgardQueryBuilder has been initialized for.

In case of any error, MidgardConnection error is set.

builder :

MidgardQueryBuilder instance

n_objects :

a pointer to store number of returned objects

Returns :

NULL terminated array of objects, or NULL if none found. [transfer full]

midgard_query_builder_count ()

guint               midgard_query_builder_count         (MidgardQueryBuilder *builder);

Returns the number of objects that this query would return when executed without limit or start offset settings.

builder :

MidgardQueryBuilder instance

Returns :

number of object matched by this query

midgard_query_builder_get_type_name ()

const gchar *       midgard_query_builder_get_type_name (MidgardQueryBuilder *builder);

Returns type name of the type which is currently used by Query Builder.

This function should be used on language binding level , when internal Query Builder's instance is already created and language binding object should be instanciated.

Returned type name is a pointer and is owned by GLib system. Caller shouldn't free it.

builder :

MidgardQueryBuilder instance

Returns :

name of the class, which query builder is initialized for.

midgard_query_builder_include_deleted ()

void                midgard_query_builder_include_deleted
                                                        (MidgardQueryBuilder *builder);

Query all objects - deleted and undeleted.

This is valid for a class for which metadata is defined ('deleted' property of MidgardMetadata class), or class has 'metadata' property installed. If none of them is found, this method does nothing.

builder :

MidgardQueryBuilder instance

Signal Details

The "execution-end" signal

void                user_function                      (MidgardQueryBuilder *midgardquerybuilder,
                                                        gpointer             user_data)                : No Hooks

midgardquerybuilder :

the object which received the signal.

user_data :

user data set when the signal handler was connected.

The "execution-start" signal

void                user_function                      (MidgardQueryBuilder *midgardquerybuilder,
                                                        gpointer             user_data)                : No Hooks

midgardquerybuilder :

the object which received the signal.

user_data :

user data set when the signal handler was connected.