/** Write the given operator to the database under the given id. * * @param session The medialib session connected to the DB. * @param collid The id under which to save the collection. * @param coll The structure of the collection to save. * @return The next free collection id. */ static guint xmms_collection_dbwrite_operator (xmms_medialib_session_t *session, guint collid, xmmsv_coll_t *coll) { gchar query[128]; guint *idlist; gint i; xmmsv_coll_t *op; xmmsv_t *attrs; gint newid, nextid; coll_dbwrite_t dbwrite_infos = { session, collid, 0 }; /* Write operator */ g_snprintf (query, sizeof (query), "INSERT INTO CollectionOperators VALUES(%d, %d)", collid, xmmsv_coll_get_type (coll)); xmms_medialib_select (session, query, NULL); /* Write attributes */ attrs = xmmsv_coll_attributes_get (coll); xmmsv_dict_foreach (attrs, dbwrite_coll_attributes, &dbwrite_infos); attrs = NULL; /* no unref needed. */ /* Write idlist */ idlist = xmmsv_coll_get_idlist (coll); for (i = 0; idlist[i] != 0; i++) { g_snprintf (query, sizeof (query), "INSERT INTO CollectionIdlists VALUES(%d, %d, %d)", collid, i, idlist[i]); xmms_medialib_select (session, query, NULL); } /* Save operands and connections (don't recurse in ref operand) */ newid = collid + 1; if (xmmsv_coll_get_type (coll) != XMMS_COLLECTION_TYPE_REFERENCE) { xmmsv_t *tmp; xmmsv_list_iter_t *iter; 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)) { xmmsv_list_iter_entry (iter, &tmp); xmmsv_get_coll (tmp, &op); nextid = xmms_collection_dbwrite_operator (session, newid, op); g_snprintf (query, sizeof (query), "INSERT INTO CollectionConnections VALUES(%d, %d)", newid, collid); xmms_medialib_select (session, query, NULL); newid = nextid; } xmmsv_list_iter_explicit_destroy (iter); } /* return next available id */ return newid; }
/* 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; } }