int xmmsv_coll_compare (xmmsv_t *a, xmmsv_t *b) { xmmsv_coll_type_t type; xmmsv_t *_a, *_b; type = xmmsv_coll_get_type (a); if (xmmsv_coll_get_type (b) != type) { return 0; } _a = xmmsv_coll_idlist_get (a); _b = xmmsv_coll_idlist_get (b); if (!xmmsv_compare (_a, _b)) { return 0; } _a = xmmsv_coll_attributes_get (a); _b = xmmsv_coll_attributes_get (b); if (!xmmsv_compare (_a, _b)) { return 0; } _a = xmmsv_coll_operands_get (a); _b = xmmsv_coll_operands_get (b); if (!xmmsv_compare (_a, _b)) { return 0; } return 1; }
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"); } }
CollPtr PartyShuffle::getOperand() const { xmmsv_t *operands, *operand; // Find the operand operands = xmmsv_coll_operands_get( coll_ ); if( !xmmsv_list_get( operands, 0, &operand ) ) { throw missing_operand_error( "No operand in this operator!" ); } return CollResult::createColl( operand ); }
void configure_playlist (xmmsc_result_t *res, cli_infos_t *infos, gchar *playlist, gint history, gint upcoming, xmmsv_coll_type_t type, gchar *input) { xmmsc_result_t *saveres; xmmsv_coll_t *coll; xmmsv_coll_t *newcoll; xmmsv_t *val; gboolean copied = FALSE; val = xmmsc_result_get_value (res); if (xmmsv_get_coll (val, &coll)) { if (type >= 0 && xmmsv_coll_get_type (coll) != type) { newcoll = coll_copy_retype (coll, type); coll = newcoll; copied = TRUE; } if (history >= 0) { coll_int_attribute_set (coll, "history", history); } if (upcoming >= 0) { coll_int_attribute_set (coll, "upcoming", upcoming); } if (input) { /* Replace previous operand. */ newcoll = coll_make_reference (input, XMMS_COLLECTION_NS_COLLECTIONS); xmmsv_list_clear (xmmsv_coll_operands_get (coll)); xmmsv_coll_add_operand (coll, newcoll); xmmsv_coll_unref (newcoll); } saveres = xmmsc_coll_save (infos->sync, coll, playlist, XMMS_COLLECTION_NS_PLAYLISTS); xmmsc_result_wait (saveres); done (saveres, infos); } else { g_printf (_("Cannot find the playlist to configure!\n")); cli_infos_loop_resume (infos); } if (copied) { xmmsv_coll_unref (coll); } xmmsc_result_unref (res); }
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); } } }
static VALUE c_operands_each (VALUE self) { RbCollection *coll = NULL; xmmsv_t *operands_list; VALUE tmp; tmp = rb_iv_get (self, "collection"); Data_Get_Struct (tmp, RbCollection, coll); operands_list = xmmsv_coll_operands_get (coll->real); xmmsv_list_foreach (operands_list, operands_each, NULL); return self; }
xmmsv_coll_t * xmmsv_coll_copy (xmmsv_coll_t *orig_coll) { xmmsv_coll_t *new_coll, *coll_elem; xmmsv_list_iter_t *it; xmmsv_dict_iter_t *itd; xmmsv_t *v, *list, *dict; const char *key; int32_t i; const char *s; new_coll = xmmsv_coll_new (xmmsv_coll_get_type (orig_coll)); list = xmmsv_coll_idlist_get (orig_coll); x_return_val_if_fail (xmmsv_get_list_iter (list, &it), NULL); while (xmmsv_list_iter_valid (it)) { xmmsv_list_iter_entry (it, &v); xmmsv_get_int (v, &i); xmmsv_coll_idlist_append (new_coll, i); xmmsv_list_iter_next (it); } xmmsv_list_iter_explicit_destroy (it); list = xmmsv_coll_operands_get (orig_coll); x_return_val_if_fail (xmmsv_get_list_iter (list, &it), NULL); while (xmmsv_list_iter_valid (it)) { xmmsv_list_iter_entry (it, &v); xmmsv_get_coll (v, &coll_elem); xmmsv_coll_add_operand (new_coll, xmmsv_coll_copy (coll_elem)); xmmsv_list_iter_next (it); } xmmsv_list_iter_explicit_destroy (it); dict = xmmsv_coll_attributes_get (orig_coll); x_return_val_if_fail (xmmsv_get_dict_iter (dict, &itd), NULL); while (xmmsv_dict_iter_valid (itd)) { xmmsv_dict_iter_pair (itd, &key, &v); xmmsv_get_string (v, &s); xmmsv_coll_attribute_set (new_coll, key, s); xmmsv_dict_iter_next (itd); } xmmsv_dict_iter_explicit_destroy (itd); return new_coll; }
static void pl_print_config (xmmsv_coll_t *coll, const char *name) { xmmsv_coll_t *op; xmmsv_coll_type_t type; gchar *upcoming = NULL; gchar *history = NULL; gchar *input = NULL; gchar *input_ns = NULL; xmmsv_t *v; type = xmmsv_coll_get_type (coll); xmmsv_coll_attribute_get (coll, "upcoming", &upcoming); xmmsv_coll_attribute_get (coll, "history", &history); g_printf (_("name: %s\n"), name); switch (type) { case XMMS_COLLECTION_TYPE_IDLIST: g_printf (_("type: list\n")); break; case XMMS_COLLECTION_TYPE_QUEUE: g_printf (_("type: queue\n")); g_printf (_("history: %s\n"), history); break; case XMMS_COLLECTION_TYPE_PARTYSHUFFLE: if (xmmsv_list_get (xmmsv_coll_operands_get (coll), 0, &v) && xmmsv_get_coll (v, &op)) { xmmsv_coll_attribute_get (op, "reference", &input); xmmsv_coll_attribute_get (op, "namespace", &input_ns); } g_printf (_("type: pshuffle\n")); g_printf (_("history: %s\n"), history); g_printf (_("upcoming: %s\n"), upcoming); g_printf (_("input: %s/%s\n"), input_ns, input); break; default: g_printf (_("type: unknown!\n")); break; } }
static void xmms_playlist_update_partyshuffle (xmms_playlist_t *playlist, const gchar *plname, xmmsv_coll_t *coll) { gint history, upcoming, currpos, size; xmmsv_coll_t *src; xmmsv_t *tmp; XMMS_DBG ("PLAYLIST: Update partyshuffle."); if (!xmms_collection_get_int_attr (coll, "history", &history)) { history = 0; } if (!xmms_collection_get_int_attr (coll, "upcoming", &upcoming)) { upcoming = XMMS_DEFAULT_PARTYSHUFFLE_UPCOMING; } currpos = xmms_playlist_coll_get_currpos (coll); while (currpos > history) { /* Removing entries is fast enough to be processed at once. */ xmms_playlist_remove_unlocked (playlist, plname, coll, 0, NULL); currpos = xmms_playlist_coll_get_currpos (coll); } g_return_if_fail(xmmsv_list_get (xmmsv_coll_operands_get (coll), 0, &tmp)); g_return_if_fail(xmmsv_get_coll (tmp, &src)); /* Since getting random media can be slow on huge medialibs, we refill only * one entry at a time. This let other threads a chance to get the lock on * the playlist object as soon as possible. */ size = xmms_playlist_coll_get_size (coll); if (size < currpos + 1 + upcoming) { xmms_medialib_entry_t randentry; randentry = xmms_collection_get_random_media (playlist->colldag, src); if (randentry > 0) { xmms_playlist_add_entry_unlocked (playlist, plname, coll, randentry, NULL); } } }
static void _xmms_coll_dump (xmmsv_t *coll, int indent) { xmmsv_t *attributes, *operands, *idlist; const char *type_str; printf ("/* collection */ {\n"); type_str = collection_type_string (xmmsv_coll_get_type (coll)); _xmmsv_coll_dump_indent (indent + 1); printf ("'type': '%s'", type_str); attributes = xmmsv_coll_attributes_get (coll); if (xmmsv_dict_get_size (attributes)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'attributes': "); xmmsv_dump_indented (attributes, indent + 1); } operands = xmmsv_coll_operands_get (coll); if (xmmsv_list_get_size (operands)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'operands': "); xmmsv_dump_indented (operands, indent + 1); } idlist = xmmsv_coll_idlist_get (coll); if (xmmsv_list_get_size (idlist)) { printf (",\n"); _xmmsv_coll_dump_indent (indent + 1); printf ("'idlist': "); xmmsv_dump_indented (idlist, indent + 1); } printf ("\n"); _xmmsv_coll_dump_indent (indent); printf ("}"); }
static xmmsv_t * duplicate_coll_value (xmmsv_t *val) { xmmsv_t *dup_val, *attributes, *operands, *idlist, *copy; dup_val = xmmsv_new_coll (xmmsv_coll_get_type (val)); attributes = xmmsv_coll_attributes_get (val); copy = xmmsv_copy (attributes); xmmsv_coll_attributes_set (dup_val, copy); xmmsv_unref (copy); operands = xmmsv_coll_operands_get (val); copy = xmmsv_copy (operands); xmmsv_coll_operands_set (dup_val, copy); xmmsv_unref (copy); idlist = xmmsv_coll_idlist_get (val); copy = xmmsv_copy (idlist); xmmsv_coll_idlist_set (dup_val, copy); xmmsv_unref (copy); return dup_val; }
/* 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; } }
/* Dump the structure of the collection as a string (from src/clients/cli/cmd_coll.c) */ static void coll_dump (xmmsv_coll_t *coll, guint level) { gint i; gchar *indent; gchar *attr1; gchar *attr2; xmmsv_coll_t *operand; GString *idlist_str; indent = g_malloc ((level * 2) + 1); for (i = 0; i < level * 2; ++i) { indent[i] = ' '; } indent[i] = '\0'; /* type */ switch (xmmsc_coll_get_type (coll)) { case XMMS_COLLECTION_TYPE_REFERENCE: xmmsc_coll_attribute_get (coll, "reference", &attr1); print_info ("%sReference: '%s'", indent, attr1); break; case XMMS_COLLECTION_TYPE_UNION: print_info ("%sUnion:", indent); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; case XMMS_COLLECTION_TYPE_INTERSECTION: print_info ("%sIntersection:", indent); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; case XMMS_COLLECTION_TYPE_COMPLEMENT: print_info ("%sComplement:", indent); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; case XMMS_COLLECTION_TYPE_EQUALS: xmmsc_coll_attribute_get (coll, "field", &attr1); xmmsc_coll_attribute_get (coll, "value", &attr2); print_info ("%sEquals ('%s', '%s') for:", indent, attr1, attr2); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; case XMMS_COLLECTION_TYPE_HAS: xmmsc_coll_attribute_get (coll, "field", &attr1); print_info ("%sHas ('%s') for:", indent, attr1); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; case XMMS_COLLECTION_TYPE_MATCH: xmmsc_coll_attribute_get (coll, "field", &attr1); xmmsc_coll_attribute_get (coll, "value", &attr2); print_info ("%sMatch ('%s', '%s') for:", indent, attr1, attr2); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; case XMMS_COLLECTION_TYPE_SMALLER: xmmsc_coll_attribute_get (coll, "field", &attr1); xmmsc_coll_attribute_get (coll, "value", &attr2); print_info ("%sSmaller ('%s', '%s') for:", indent, attr1, attr2); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; case XMMS_COLLECTION_TYPE_GREATER: xmmsc_coll_attribute_get (coll, "field", &attr1); xmmsc_coll_attribute_get (coll, "value", &attr2); print_info ("%sGreater ('%s', '%s') for:", indent, attr1, attr2); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; case XMMS_COLLECTION_TYPE_IDLIST: idlist_str = coll_idlist_to_string (coll); print_info ("%sIdlist: %s", indent, idlist_str->str); g_string_free (idlist_str, TRUE); break; case XMMS_COLLECTION_TYPE_QUEUE: idlist_str = coll_idlist_to_string (coll); print_info ("%sQueue: %s", indent, idlist_str->str); g_string_free (idlist_str, TRUE); break; case XMMS_COLLECTION_TYPE_PARTYSHUFFLE: idlist_str = coll_idlist_to_string (coll); print_info ("%sParty Shuffle: %s from :", indent, idlist_str->str); g_string_free (idlist_str, TRUE); coll_dump_list (xmmsv_coll_operands_get (coll), level + 1); break; default: print_info ("%sUnknown Operator!", indent); break; } }
void OperandIterator::initIterator() { xmmsv_t *operands( xmmsv_coll_operands_get( coll_.coll_ ) ); xmmsv_get_list_iter( operands, &oper_it_ ); }
static bool _internal_put_on_bb_collection (xmmsv_t *bb, xmmsv_coll_t *coll) { xmmsv_list_iter_t *it; xmmsv_t *v, *attrs; int n; uint32_t ret; int32_t entry; xmmsv_coll_t *op; if (!bb || !coll) { return false; } /* push type */ if (!xmmsv_bitbuffer_put_bits (bb, 32, xmmsv_coll_get_type (coll))) return false; /* attribute counter and values */ attrs = xmmsv_coll_attributes_get (coll); n = 0; xmmsv_dict_foreach (attrs, _internal_put_on_bb_count_coll_attr, &n); if (!xmmsv_bitbuffer_put_bits (bb, 32, n)) return false; /* needs error checking! */ xmmsv_dict_foreach (attrs, _internal_put_on_bb_append_coll_attr, bb); attrs = NULL; /* no unref needed. */ /* idlist counter and content */ xmmsv_bitbuffer_put_bits (bb, 32, xmmsv_coll_idlist_get_size (coll)); xmmsv_get_list_iter (xmmsv_coll_idlist_get (coll), &it); for (xmmsv_list_iter_first (it); xmmsv_list_iter_valid (it); xmmsv_list_iter_next (it)) { if (!xmmsv_list_iter_entry_int (it, &entry)) { x_api_error ("Non integer in idlist", 0); } xmmsv_bitbuffer_put_bits (bb, 32, entry); } xmmsv_list_iter_explicit_destroy (it); /* operands counter and objects */ n = 0; if (xmmsv_coll_get_type (coll) != XMMS_COLLECTION_TYPE_REFERENCE) { n = xmmsv_list_get_size (xmmsv_coll_operands_get (coll)); } ret = xmmsv_bitbuffer_pos (bb); xmmsv_bitbuffer_put_bits (bb, 32, n); if (n > 0) { xmmsv_get_list_iter (xmmsv_coll_operands_get (coll), &it); while (xmmsv_list_iter_entry (it, &v)) { if (!xmmsv_get_coll (v, &op)) { x_api_error ("Non collection operand", 0); } _internal_put_on_bb_int32 (bb, XMMSV_TYPE_COLL); ret = _internal_put_on_bb_collection (bb, op); xmmsv_list_iter_next (it); } } return ret; }
/** 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; }