static void add_sql(MidgardGroupConstraint *group, GString *sql) { g_assert(group != NULL); g_assert(sql != NULL); GSList *list = NULL; GSList *jlist = NULL; GSList *glist = NULL; guint i = 0; if(g_slist_length(group->constraints) == 0 && g_slist_length(group->nested) == 0) { g_string_append(sql, "1=1"); return; } if(g_slist_length(group->constraints) == 1 && g_slist_length(group->nested) == 0) { g_string_append(sql, MIDGARD_CORE_QUERY_CONSTRAINT(group->constraints->data)->priv->condition); return; } g_string_append_c(sql, '('); for(list = group->constraints; list != NULL; list = list->next) { if(i > 0) g_string_append_printf(sql, " %s ", group->type); g_string_append(sql, MIDGARD_CORE_QUERY_CONSTRAINT(list->data)->priv->condition); i++; } for(glist = group->nested; glist != NULL; glist = glist->next) { if(i > 0) g_string_append_printf(sql, " %s ", group->type); MidgardGroupConstraint *ngroup = MIDGARD_GROUP_CONSTRAINT(glist->data); MidgardGroupConstraintClass *klass = MIDGARD_GROUP_CONSTRAINT_GET_CLASS(ngroup); klass->add_sql(ngroup, sql); i++; } g_string_append_c(sql, ')'); list = NULL; for(list = group->constraints; list != NULL; list = list->next) { for(jlist = ((MidgardCoreQueryConstraint*)list->data)->priv->joins; jlist != NULL; jlist = jlist->next) { g_string_append(sql, " AND "); g_string_append(sql, ((MidgardCoreQueryConstraintPrivate*)jlist->data)->condition); } } }
gchar *midgard_core_qb_get_sql( MidgardQueryBuilder *builder, guint mode, gchar *select) { g_assert (builder != NULL); g_assert (builder->priv->schema->table); /* FIXME, error reporting needed */ if (builder->priv->error != 0) { g_warning("Can not create query"); return NULL; } /* SELECT */ GString *sql = g_string_new ("SELECT "); if (builder->priv->select_distinct) g_string_append (sql, "DISTINCT "); g_string_append (sql, select); g_free (select); /* FROM */ g_string_append (sql, " FROM "); GSList *tlist = NULL; g_hash_table_foreach (builder->priv->tables, _add_table_foreach, &tlist); GString *tables = g_string_new (""); guint l = 0; GSList *nlist; for (nlist = tlist; nlist != NULL; nlist = nlist->next) { if(l < 1) g_string_append(tables, (gchar *) nlist->data); else g_string_append_printf(tables, ", %s", (gchar *) nlist->data); l++; } if(tlist) g_slist_free(tlist); g_string_append(sql, tables->str); /* WHERE */ g_string_append(sql, " WHERE "); __sql_add_constraints(sql, builder); g_string_free(tables, TRUE); /* OR&AND groupings */ guint i = 0; builder->priv->groups = g_slist_reverse(builder->priv->groups); if(builder->priv->groups != NULL) { if(builder->priv->constraints) g_string_append(sql, " AND "); GSList *glist = NULL; MidgardGroupConstraintClass *klass; for(glist = builder->priv->groups; glist != NULL; glist = glist->next) { if(i > 0) g_string_append(sql, " AND "); klass = MIDGARD_GROUP_CONSTRAINT_GET_CLASS( MIDGARD_GROUP_CONSTRAINT(glist->data)); klass->add_sql(MIDGARD_GROUP_CONSTRAINT(glist->data), sql); i++; } } /* Join tables from ORDER BY */ GSList *olist = NULL; GSList *jlist = NULL; if(builder->priv->orders != NULL) { for(olist = builder->priv->orders; olist != NULL; olist = olist->next) { for(jlist = ((MidgardQueryOrder*)olist->data)->constraint->priv->joins; jlist != NULL; jlist = jlist->next) { g_string_append(sql, " AND "); g_string_append(sql, ((MidgardCoreQueryConstraintPrivate*)jlist->data)->condition); } } } /* Add joins */ if(builder->priv->joins != NULL) { for(jlist = builder->priv->joins; jlist != NULL; jlist = jlist->next) { g_string_append(sql, " AND "); g_string_append(sql, ((MidgardCoreQueryConstraintPrivate*)jlist->data)->condition); } } MidgardDBObjectClass *dbklass = g_type_class_peek(builder->priv->type); if(!builder->priv->include_deleted) { const gchar *deleted_field = midgard_core_object_get_deleted_field (dbklass); if (deleted_field) { g_string_append(sql, " AND "); g_string_append_printf(sql, " %s.%s = FALSE", builder->priv->schema->table, deleted_field); } } /* ORDER BY */ olist = NULL; i = 0; if(builder->priv->orders != NULL) { g_string_append(sql, " ORDER BY "); for(olist = builder->priv->orders; olist != NULL; olist = olist->next) { if(i > 0) g_string_append(sql, ", "); MidgardQueryOrder *order = (MidgardQueryOrder *)olist->data; g_string_append(sql, midgard_core_query_order_get_sql(order)); i++; } } if (mode < MQB_SELECT_COUNT && builder->priv->limit != G_MAXUINT) g_string_append_printf(sql, " LIMIT %u", builder->priv->limit); if (builder->priv->offset != 0) g_string_append_printf(sql, " OFFSET %u", builder->priv->offset); return g_string_free(sql, FALSE); }