00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <config.h>
00020 #include "group_constraint.h"
00021
00022 static void add_sql(MidgardQueryConstraint *constraint, GString *sql) {
00023 g_assert(constraint);
00024 g_assert(sql);
00025
00026 MidgardGroupConstraint *group = MIDGARD_GROUP_CONSTRAINT(constraint);
00027 switch (g_queue_get_length(group->constraints)) {
00028 case 0:
00029 g_string_append(sql, "1 = 1");
00030 break;
00031 case 1:
00032 midgard_query_constraint_add_sql(
00033 MIDGARD_QUERY_CONSTRAINT(g_queue_peek_head(group->constraints)), sql);
00034 break;
00035 default:
00036 g_string_append(sql, "(");
00037 GList *item = group->constraints->head;
00038 while (item != NULL) {
00039 if (item != group->constraints->head) {
00040 g_string_append(sql, " ");
00041 g_string_append(sql, group->type);
00042 g_string_append(sql, " ");
00043 }
00044 midgard_query_constraint_add_sql(
00045 MIDGARD_QUERY_CONSTRAINT(item->data), sql);
00046 item = g_list_next(item);
00047 }
00048 g_string_append(sql, ")");
00049 break;
00050 }
00051 }
00052
00053 G_DEFINE_TYPE(MidgardGroupConstraint, midgard_group_constraint, MIDGARD_TYPE_QUERY_CONSTRAINT)
00054
00055 static void midgard_group_constraint_init(MidgardGroupConstraint *self) {
00056 g_assert(self);
00057 self->type = MIDGARD_GROUP_CONSTRAINT_TYPE_AND;
00058 self->constraints = g_queue_new();
00059 }
00060
00061 static void midgard_group_constraint_dispose(MidgardGroupConstraint *group) {
00062 g_assert(group);
00063
00064 GQueue *constraints = group->constraints;
00065 group->constraints = g_queue_new();
00066 while (!g_queue_is_empty(constraints)) {
00067 g_object_unref(G_OBJECT(g_queue_pop_head(constraints)));
00068 }
00069 g_queue_free(constraints);
00070
00071 GObjectClass *parent =
00072 G_OBJECT_CLASS(midgard_group_constraint_parent_class);
00073 parent->dispose(G_OBJECT(group));
00074 }
00075
00076 static void midgard_group_constraint_finalize(MidgardGroupConstraint *group) {
00077 g_assert(group);
00078
00079 g_queue_free(group->constraints);
00080
00081 GObjectClass *parent =
00082 G_OBJECT_CLASS(midgard_group_constraint_parent_class);
00083 parent->finalize(G_OBJECT(group));
00084 }
00085
00086 static void midgard_group_constraint_class_init(
00087 MidgardGroupConstraintClass *klass) {
00088 g_assert(klass);
00089 MIDGARD_QUERY_CONSTRAINT_CLASS(klass)->add_sql = add_sql;
00090 G_OBJECT_CLASS(klass)->dispose = (void (*)(GObject *self))
00091 midgard_group_constraint_dispose;
00092 G_OBJECT_CLASS(klass)->finalize = (void (*)(GObject *self))
00093 midgard_group_constraint_finalize;
00094 }
00095
00096 static const gchar *const types[] = {
00097 MIDGARD_GROUP_CONSTRAINT_TYPE_AND,
00098 MIDGARD_GROUP_CONSTRAINT_TYPE_OR,
00099 NULL
00100 };
00101
00102 MidgardGroupConstraint *midgard_group_constraint_new(const gchar *type) {
00103 g_assert(type);
00104 guint i;
00105 for (i = 0; types[i] != NULL; i++) {
00106 if (g_ascii_strcasecmp(types[i], type) == 0) {
00107 MidgardGroupConstraint *group =
00108 MIDGARD_GROUP_CONSTRAINT(g_object_new(
00109 MIDGARD_TYPE_GROUP_CONSTRAINT, NULL));
00110 group->type = types[i];
00111 return group;
00112 }
00113 }
00114 return NULL;
00115 }
00116
00117 void midgard_group_constraint_add_constraint(
00118 MidgardGroupConstraint *group,
00119 MidgardQueryConstraint *constraint) {
00120 g_assert(group);
00121 g_assert(constraint);
00122 g_object_ref(G_OBJECT(constraint));
00123 g_queue_push_tail(group->constraints, constraint);
00124 }