gchar *
midgard_cr_core_query_compute_constraint_property (MidgardCRCoreQueryExecutor *executor,
        MidgardCRCoreQueryStorage *storage, const gchar *name)
{
    g_return_val_if_fail (executor != NULL, FALSE);
    g_return_val_if_fail (name != NULL, FALSE);

    /* Set table alias if it's not set */
    if (storage)
        MQE_SET_TABLE_ALIAS (executor, storage);

    MidgardCRSQLStorageManager *manager = (MidgardCRSQLStorageManager*) executor->priv->storage_manager;
    GObjectClass *klass = g_type_class_peek (g_type_from_name (executor->priv->storage->priv->classname));
    MidgardCRSQLTableModel *table_model = midgard_cr_core_query_find_table_model_by_name (manager, executor->priv->storage->priv->classname);

    gchar *table_field = NULL;
    gchar *table_alias = executor->priv->table_alias;
    const gchar *table = midgard_cr_storage_model_get_location (MIDGARD_CR_STORAGE_MODEL (table_model));
    if (storage) {
        //table = executor->priv->storage->priv->table;
        table_alias = storage->priv->table_alias;
        klass = g_type_class_peek (g_type_from_name (storage->priv->classname));
    }

    gchar **spltd = g_strsplit(name, ".", 0);
    guint i = 0;
    guint j = 0;

    /* We can support max 3 tokens */
    while(spltd[i] != NULL)
        i++;

    gchar *q_table = NULL;
    gchar *q_field = NULL;

    /* case: property */
    if (i == 1) {
        const gchar *property_field =
            __get_property_colname (MIDGARD_CR_SQL_STORAGE_MANAGER (executor->priv->storage_manager), G_OBJECT_CLASS_NAME (klass), name);
        if (!property_field) {
            g_warning ("%s doesn't seem to be registered for %s", name, G_OBJECT_CLASS_NAME (klass));
            g_strfreev (spltd);
            return NULL;
        }
        q_table = gda_connection_quote_sql_identifier (MCQE_CNC (executor), table_alias);
        q_field = gda_connection_quote_sql_identifier (MCQE_CNC (executor), property_field);
        table_field = g_strdup_printf ("%s.%s", q_table, q_field);
    } else if (i < 4) {
        /* Set all pointers we need to generate valid tables' names, aliases or joins */
        Psh holder = {NULL, };
        holder.table = table;
        holder.table_alias = table_alias;
        holder.klass = klass;
        holder.executor = MIDGARD_CR_CORE_QUERY_EXECUTOR (executor);
        holder.colname = NULL;

        while (spltd[j] != NULL) {
            if (spltd[j+1] == NULL)
                break;
            /* Set all pointers we need to generate valid tables' names, aliases or joins */
            /* case: metadata.property, attachment.property, property.link, etc */
            if (!__compute_reserved_property_constraint (&holder, spltd[j], spltd[j+1]))
                break;
            j++;
        }

        if (holder.table_alias && holder.colname) {
            q_table = gda_connection_quote_sql_identifier (MCQE_CNC (executor), holder.table_alias);
            q_field = gda_connection_quote_sql_identifier (MCQE_CNC (executor), holder.colname);
            table_field = g_strdup_printf ("%s.%s", q_table, q_field);
        }

    } else {
        g_warning("Failed to parse '%s'. At most 3 tokens allowed", name);
    }

    g_strfreev (spltd);
    g_free (q_table);
    g_free (q_field);

    return table_field;
}
Пример #2
0
/* 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;
}