static void
query_append_operand (coll_query_t *query, xmms_coll_dag_t *dag, xmmsv_coll_t *coll)
{
	xmmsv_coll_t *op = NULL;
	gchar *target_name;
	gchar *target_ns;
	guint  target_nsid;

	if (!xmmsv_list_get_coll (xmmsv_coll_operands_get (coll), 0, &op)) {

		/* Ref'd coll not saved as operand, look for it */
		if (xmmsv_coll_attribute_get (coll, "reference", &target_name) &&
		    xmmsv_coll_attribute_get (coll, "namespace", &target_ns)) {

			target_nsid = xmms_collection_get_namespace_id (target_ns);
			op = xmms_collection_get_pointer (dag, target_name, target_nsid);
		}
	}

	/* Append reference operator */
	if (op != NULL) {
		xmms_collection_append_to_query (dag, op, query);

	/* Cannot find reference, append dummy TRUE */
	} else {
		query_append_string (query, "1");
	}
}
static void
query_append_protect_string (coll_query_t *query, gchar *s)
{
	gchar *preps;
	if ((preps = sqlite_prepare_string (s)) != NULL) {  /* FIXME: Return oom error */
		query_append_string (query, preps);
		g_free (preps);
	}
}
static void
query_append_intersect_operand (coll_query_t *query, xmms_coll_dag_t *dag,
                                xmmsv_coll_t *coll)
{
	xmmsv_coll_t *op;
	xmmsv_t *tmp;

	if (xmmsv_list_get (xmmsv_coll_operands_get (coll), 0, &tmp)) {
		xmmsv_get_coll (tmp, &op);

		if (!operator_is_allmedia (op)) {
			query_append_string (query, " AND ");
			xmms_collection_append_to_query (dag, op, query);
		}
	}
}
Example #4
0
static void
query_append_intersect_operand (coll_query_t *query, xmms_coll_dag_t *dag,
                                xmmsv_coll_t *coll)
{
	xmmsv_coll_t *op;

	xmmsv_coll_operand_list_save (coll);
	xmmsv_coll_operand_list_first (coll);
	if (xmmsv_coll_operand_list_entry (coll, &op)) {
		if (!operator_is_allmedia (op)) {
			query_append_string (query, " AND ");
			xmms_collection_append_to_query (dag, op, query);
		}
	}
	xmmsv_coll_operand_list_restore (coll);
}
/* Append a filtering clause on the field value, depending on the operator type. */
static void
query_append_filter (coll_query_t *query, xmmsv_coll_type_t type,
                     gchar *key, gchar *value, gboolean case_sens)
{
	coll_query_alias_t *alias;
	gboolean optional;
	gchar *temp;
	gint i;

	if (type == XMMS_COLLECTION_TYPE_HAS) {
		optional = TRUE;
	} else {
		optional = FALSE;
	}

	alias = query_make_alias (query, key, optional);

	switch (type) {
	/* escape strings */
	case XMMS_COLLECTION_TYPE_EQUALS:
	case XMMS_COLLECTION_TYPE_MATCH:
		if (case_sens) {
			query_string_append_alias (query->conditions, alias,
			                           COLL_QUERY_VALUE_TYPE_STRING);
		} else {
			query_append_string (query, "(");
			query_string_append_alias (query->conditions, alias,
			                           COLL_QUERY_VALUE_TYPE_STRING);
			query_append_string (query, " COLLATE NOCASE)");
		}

		if (type == XMMS_COLLECTION_TYPE_EQUALS) {
			query_append_string (query, "=");
		} else {
			if (case_sens) {
				query_append_string (query, " GLOB ");
			} else {
				query_append_string (query, " LIKE ");
			}
		}

		if (type == XMMS_COLLECTION_TYPE_MATCH && !case_sens) {
			temp = g_strdup(value);
			for (i = 0; temp[i]; i++) {
				switch (temp[i]) {
					case '*': temp[i] = '%'; break;
					case '?': temp[i] = '_'; break;
					default :                break;
				}
			}
			query_append_protect_string (query, temp);
			g_free(temp);
		} else {
			query_append_protect_string (query, value);
		}
		break;

	/* do not escape numerical values */
	case XMMS_COLLECTION_TYPE_SMALLER:
	case XMMS_COLLECTION_TYPE_GREATER:
		query_string_append_alias (query->conditions, alias,
		                           COLL_QUERY_VALUE_TYPE_INT);
		if (type == XMMS_COLLECTION_TYPE_SMALLER) {
			query_append_string (query, " < ");
		} else {
			query_append_string (query, " > ");
		}
		query_append_string (query, value);
		break;

	case XMMS_COLLECTION_TYPE_HAS:
		query_string_append_alias (query->conditions, alias,
		                           COLL_QUERY_VALUE_TYPE_STRING);
		query_append_string (query, " is not null");
		break;

	/* Called with invalid type? */
	default:
		g_assert_not_reached ();
		break;
	}
}
/* Recursively append conditions corresponding to the given collection to the query. */
static void
xmms_collection_append_to_query (xmms_coll_dag_t *dag, xmmsv_coll_t *coll,
                                 coll_query_t *query)
{
	xmmsv_coll_t *op;
	xmms_medialib_entry_t entry;
	gchar *attr1, *attr2, *attr3;
	gboolean case_sens;
	xmmsv_list_iter_t *iter;
	xmmsv_t *tmp;
	gboolean first;

	xmmsv_coll_type_t type = xmmsv_coll_get_type (coll);
	switch (type) {
	case XMMS_COLLECTION_TYPE_REFERENCE:
		if (!operator_is_allmedia (coll)) {
			query_append_operand (query, dag, coll);
		} else {
			/* FIXME: Hackish solution to append a ref to All Media */
			query_append_string (query, "1");
		}
		break;

	case XMMS_COLLECTION_TYPE_UNION:
	case XMMS_COLLECTION_TYPE_INTERSECTION:
		first = TRUE;
		query_append_string (query, "(");

		xmmsv_get_list_iter (xmmsv_coll_operands_get (coll), &iter);

		for (xmmsv_list_iter_first (iter);
		     xmmsv_list_iter_valid (iter);
		     xmmsv_list_iter_next (iter)) {
			if (first) {
				first = FALSE;
			} else {
				if (type == XMMS_COLLECTION_TYPE_UNION)
					query_append_string (query, " OR ");
				else
					query_append_string (query, " AND ");
			}
			xmmsv_list_iter_entry (iter, &tmp);
			xmmsv_get_coll (tmp, &op);
			xmms_collection_append_to_query (dag, op, query);
		}
		xmmsv_list_iter_explicit_destroy (iter);

		query_append_string (query, ")");
		break;

	case XMMS_COLLECTION_TYPE_COMPLEMENT:
		query_append_string (query, "NOT ");
		query_append_operand (query, dag, coll);
		break;

	case XMMS_COLLECTION_TYPE_HAS:
	case XMMS_COLLECTION_TYPE_EQUALS:
	case XMMS_COLLECTION_TYPE_MATCH:
	case XMMS_COLLECTION_TYPE_SMALLER:
	case XMMS_COLLECTION_TYPE_GREATER:
		xmmsv_coll_attribute_get (coll, "field", &attr1);
		xmmsv_coll_attribute_get (coll, "value", &attr2);
		xmmsv_coll_attribute_get (coll, "case-sensitive", &attr3);
		case_sens = (attr3 != NULL && strcmp (attr3, "true") == 0);

		query_append_string (query, "(");
		query_append_filter (query, type, attr1, attr2, case_sens);

		query_append_intersect_operand (query, dag, coll);
		query_append_string (query, ")");
		break;

	case XMMS_COLLECTION_TYPE_IDLIST:
	case XMMS_COLLECTION_TYPE_QUEUE:
	case XMMS_COLLECTION_TYPE_PARTYSHUFFLE:
		first = TRUE;
		query_append_string (query, "m0.id IN (");

		xmmsv_get_list_iter (xmmsv_coll_idlist_get (coll), &iter);
		for (xmmsv_list_iter_first (iter);
		     xmmsv_list_iter_valid (iter);
		     xmmsv_list_iter_next (iter)) {

			if (first) {
				first = FALSE;
			} else {
				query_append_string (query, ",");
			}

			xmmsv_list_iter_entry_int (iter, &entry);
			query_append_int (query, entry);
		}
		xmmsv_list_iter_explicit_destroy (iter);

		query_append_string (query, ")");
		break;

	/* invalid type */
	default:
		XMMS_DBG ("Cannot append invalid collection operator!");
		g_assert_not_reached ();
		break;
	}

}
Example #7
0
/* Recursively append conditions corresponding to the given collection to the query. */
static void
xmms_collection_append_to_query (xmms_coll_dag_t *dag, xmmsv_coll_t *coll,
                                 coll_query_t *query)
{
	gint i;
	xmmsv_coll_t *op;
	guint *idlist;
	gchar *attr1, *attr2, *attr3;
	gboolean case_sens;

	xmmsv_coll_type_t type = xmmsv_coll_get_type (coll);
	switch (type) {
	case XMMS_COLLECTION_TYPE_REFERENCE:
		if (!operator_is_allmedia (coll)) {
			query_append_operand (query, dag, coll);
		} else {
			/* FIXME: Hackish solution to append a ref to All Media */
			query_append_string (query, "1");
		}
		break;

	case XMMS_COLLECTION_TYPE_UNION:
	case XMMS_COLLECTION_TYPE_INTERSECTION:
		i = 0;
		query_append_string (query, "(");

		xmmsv_coll_operand_list_save (coll);
		xmmsv_coll_operand_list_first (coll);
		while (xmmsv_coll_operand_list_entry (coll, &op)) {
			if (i != 0) {
				if (type == XMMS_COLLECTION_TYPE_UNION)
					query_append_string (query, " OR ");
				else
					query_append_string (query, " AND ");
			} else {
				i = 1;
			}
			xmms_collection_append_to_query (dag, op, query);
			xmmsv_coll_operand_list_next (coll);
		}
		xmmsv_coll_operand_list_restore (coll);

		query_append_string (query, ")");
		break;

	case XMMS_COLLECTION_TYPE_COMPLEMENT:
		query_append_string (query, "NOT ");
		query_append_operand (query, dag, coll);
		break;

	case XMMS_COLLECTION_TYPE_HAS:
	case XMMS_COLLECTION_TYPE_EQUALS:
	case XMMS_COLLECTION_TYPE_MATCH:
	case XMMS_COLLECTION_TYPE_SMALLER:
	case XMMS_COLLECTION_TYPE_GREATER:
		xmmsv_coll_attribute_get (coll, "field", &attr1);
		xmmsv_coll_attribute_get (coll, "value", &attr2);
		xmmsv_coll_attribute_get (coll, "case-sensitive", &attr3);
		case_sens = (attr3 != NULL && strcmp (attr3, "true") == 0);

		query_append_string (query, "(");
		query_append_filter (query, type, attr1, attr2, case_sens);

		query_append_intersect_operand (query, dag, coll);
		query_append_string (query, ")");
		break;

	case XMMS_COLLECTION_TYPE_IDLIST:
	case XMMS_COLLECTION_TYPE_QUEUE:
	case XMMS_COLLECTION_TYPE_PARTYSHUFFLE:
		idlist = xmmsv_coll_get_idlist (coll);
		query_append_string (query, "m0.id IN (");
		for (i = 0; idlist[i] != 0; ++i) {
			if (i != 0) {
				query_append_string (query, ",");
			}
			query_append_uint (query, idlist[i]);
		}
		query_append_string (query, ")");
		break;

	/* invalid type */
	default:
		XMMS_DBG ("Cannot append invalid collection operator!");
		g_assert_not_reached ();
		break;
	}

}