Exemplo n.º 1
0
static void
xmms_medialib_property_remove (xmms_medialib_session_t *session,
                               xmms_medialib_entry_t entry,
                               const gchar *source, const gchar *key,
                               xmms_error_t *error)
{
	const char *sources[2] = { source, NULL };
	s4_sourcepref_t *sp;
	s4_resultset_t *set;
	const s4_result_t *res;
	s4_val_t *song_id;

	sp = s4_sourcepref_create (sources);

	song_id = s4_val_new_int (entry);
	set = xmms_medialib_filter (session, "song_id", song_id,
	                            S4_COND_PARENT, sp, key, S4_FETCH_DATA);

	res = s4_resultset_get_result (set, 0, 0);
	if (res != NULL) {
		xmms_medialib_session_property_unset (session, entry, key,
		                                      s4_result_get_val (res),
		                                      source);
	}

	s4_resultset_free (set);
	s4_sourcepref_unref (sp);
	s4_val_free (song_id);
}
Exemplo n.º 2
0
static xmms_fetch_spec_t *
xmms_fetch_spec_new_organize (xmmsv_t *fetch, xmms_fetch_info_t *info,
                              s4_sourcepref_t *prefs, xmms_error_t *err)
{
	xmms_fetch_spec_t *spec;
	xmmsv_dict_iter_t *it;
	s4_sourcepref_t *sp;
	xmmsv_t *org_data;
	gint org_idx;

	if (!xmmsv_dict_get (fetch, "data", &org_data)) {
		xmms_error_set (err, XMMS_ERROR_INVAL, "Required field 'data' not set in organize.");
		return NULL;
	}

	if (xmmsv_get_type (org_data) != XMMSV_TYPE_DICT) {
		xmms_error_set (err, XMMS_ERROR_INVAL, "Field 'data' in organize must be a dict.");
		return NULL;
	}

	sp = normalize_source_preferences (fetch, prefs, err);
	if (xmms_error_iserror (err)) {
		return NULL;
	}

	spec = g_new0 (xmms_fetch_spec_t, 1);
	spec->type = FETCH_ORGANIZE;

	spec->data.organize.count = xmmsv_dict_get_size (org_data);
	spec->data.organize.keys = g_new0 (const char *, spec->data.organize.count);
	spec->data.organize.data = g_new0 (xmms_fetch_spec_t *, spec->data.organize.count);

	org_idx = 0;
	xmmsv_get_dict_iter (org_data, &it);
	while (xmmsv_dict_iter_valid (it)) {
		xmms_fetch_spec_t *orgee;
		const gchar *str;
		xmmsv_t *entry;

		xmmsv_dict_iter_pair (it, &str, &entry);

		orgee = xmms_fetch_spec_new (entry, info, sp, err);
		if (xmms_error_iserror (err)) {
			xmms_fetch_spec_free (spec);
			spec = NULL;
			break;
		}

		spec->data.organize.keys[org_idx] = str;
		spec->data.organize.data[org_idx] = orgee;

		org_idx++;
		xmmsv_dict_iter_next (it);
	}
	xmmsv_dict_iter_explicit_destroy (it);

	s4_sourcepref_unref (sp);

	return spec;
}
Exemplo n.º 3
0
/**
 * @internal
 */
static xmms_medialib_entry_t
xmms_medialib_get_id (xmms_medialib_session_t *session, const char *url, xmms_error_t *error)
{
	s4_sourcepref_t *sourcepref;
	s4_resultset_t *set;
	s4_val_t *value;
	const s4_result_t *res;
	gint32 id = 0;

	sourcepref = xmms_medialib_session_get_source_preferences (session);

	value = s4_val_new_string (url);
	set = xmms_medialib_filter (session, XMMS_MEDIALIB_ENTRY_PROPERTY_URL,
	                            value, 0, sourcepref, "song_id", S4_FETCH_PARENT);
	s4_val_free (value);
	s4_sourcepref_unref (sourcepref);

	res = s4_resultset_get_result (set, 0, 0);
	if (res != NULL) {
		s4_val_get_int (s4_result_get_val (res), &id);
	}

	s4_resultset_free (set);

	return id;
}
Exemplo n.º 4
0
static xmms_fetch_spec_t *
xmms_fetch_spec_new_metadata (xmmsv_t *fetch, xmms_fetch_info_t *info,
                              s4_sourcepref_t *prefs, xmms_error_t *err)
{
	xmms_fetch_spec_t *ret = NULL;
	s4_sourcepref_t *sp;
	const gchar *key;
	xmmsv_t *gets, *fields;
	gint i, size, aggregate, get;

	aggregate = normalize_aggregate_function (fetch, err);
	if (xmms_error_iserror (err)) {
		return NULL;
	}

	fields = normalize_metadata_fields (fetch, err);
	if (xmms_error_iserror (err)) {
		return NULL;
	}

	gets = normalize_metadata_get (fetch, err);
	if (xmms_error_iserror (err)) {
		return NULL;
	}

	sp = normalize_source_preferences (fetch, prefs, err);
	if (xmms_error_iserror (err)) {
		xmmsv_unref (gets);
		return NULL;
	}

	ret = g_new0 (xmms_fetch_spec_t, 1);
	ret->type = FETCH_METADATA;
	ret->data.metadata.aggr_func = aggregate;

	for (i = 0; i < 4 && xmmsv_list_get_int (gets, i, &get); i++) {
		ret->data.metadata.get[i] = get;
	}
	ret->data.metadata.get_size = i;

	if (fields != NULL) {
		size = xmmsv_list_get_size (fields);
		ret->data.metadata.col_count = size;
		ret->data.metadata.cols = g_new (gint32, size);
		for (i = 0; xmmsv_list_get_string (fields, i, &key); i++) {
			ret->data.metadata.cols[i] = xmms_fetch_info_add_key (info, fetch, key, sp);
		}
	} else {
		/* No fields requested, fetching all available */
		ret->data.metadata.col_count = 1;
		ret->data.metadata.cols = g_new0 (gint32, 1);
		ret->data.metadata.cols[0] = xmms_fetch_info_add_key (info, fetch, NULL, sp);
	}

	s4_sourcepref_unref (sp);
	xmmsv_unref (gets);

	return ret;
}
Exemplo n.º 5
0
gint
xmms_medialib_session_property_set (xmms_medialib_session_t *session,
                                    xmms_medialib_entry_t entry,
                                    const gchar *key,
                                    const s4_val_t *value,
                                    const gchar *source)
{
	const gchar *sources[2] = { source, NULL };
	const s4_result_t *res;
	s4_condition_t *cond;
	s4_fetchspec_t *spec;
	s4_resultset_t *set;
	s4_sourcepref_t *sp;
	s4_val_t *song_id;
	gint result;
	GHashTable *events;

	song_id = s4_val_new_int (entry);

	sp = s4_sourcepref_create (sources);

	cond = s4_cond_new_filter (S4_FILTER_EQUAL, "song_id", song_id,
	                           sp, S4_CMP_CASELESS, S4_COND_PARENT);

	spec = s4_fetchspec_create ();
	s4_fetchspec_add (spec, key, sp, S4_FETCH_DATA);

	set = s4_query (session->trans, spec, cond);
	s4_cond_free (cond);
	s4_fetchspec_free (spec);

	res = s4_resultset_get_result (set, 0, 0);
	if (res != NULL) {
		const s4_val_t *old_value = s4_result_get_val (res);
		s4_del (session->trans, "song_id", song_id,
		        key, old_value, source);
	}

	s4_resultset_free (set);
	s4_sourcepref_unref (sp);

	result = s4_add (session->trans, "song_id", song_id,
	                 key, value, source);

	s4_val_free (song_id);

	if (strcmp (key, XMMS_MEDIALIB_ENTRY_PROPERTY_URL) == 0) {
		events = xmms_medialib_session_get_table (&session->added);
	} else {
		events = xmms_medialib_session_get_table (&session->updated);
	}

	g_hash_table_insert (events,
	                     GINT_TO_POINTER (entry),
	                     GINT_TO_POINTER (entry));

	return result;
}
Exemplo n.º 6
0
static void
xmms_medialib_destroy (xmms_object_t *object)
{
	xmms_medialib_t *mlib = (xmms_medialib_t *) object;

	XMMS_DBG ("Deactivating medialib object.");

	s4_sourcepref_unref (mlib->default_sp);
	s4_close (mlib->s4);

	xmms_medialib_unregister_ipc_commands ();
}
Exemplo n.º 7
0
Arquivo: cond.c Projeto: dchokola/s4
/**
 * Frees a condition and operands recursively
 *
 * @param cond The condition to free
 */
void s4_cond_free (s4_condition_t *cond)
{
	if (cond->type == S4_COND_COMBINER) {
		g_ptr_array_free (cond->u.combine.operands, TRUE);
		free (cond);
	} else if (cond->type == S4_COND_FILTER) {
		if (cond->u.filter.free_func != NULL)
			cond->u.filter.free_func (cond->u.filter.funcdata);
		if (cond->u.filter.sp != NULL)
			s4_sourcepref_unref (cond->u.filter.sp);
		if (!cond->u.filter.const_key && cond->u.filter.key != NULL)
			free ((char*)cond->u.filter.key);
		free (cond);
	}
}
Exemplo n.º 8
0
/**
 * Frees a fetchspec
 * @param spec The fetchspec to free
 */
void s4_fetchspec_free (s4_fetchspec_t *spec)
{
	int i;
	for (i = 0; i < spec->array->len; i++) {
		fetch_data_t *data = &g_array_index (spec->array, fetch_data_t, i);
		if (data->pref != NULL) {
			s4_sourcepref_unref (data->pref);
		}
		if (data->key != NULL && !data->const_key) {
			free ((void*)data->key);
		}
	}
	g_array_free (spec->array, TRUE);
	free (spec);
}
Exemplo n.º 9
0
/**
 * Queries the medialib and returns an xmmsv_t with the info requested
 *
 * @param coll The collection to find
 * @param fetch Specifies what to fetch
 * @return An xmmsv_t with the structure requested in fetch
 */
xmmsv_t *
xmms_medialib_query (xmms_medialib_session_t *session, xmmsv_t *coll,
                     xmmsv_t *fetch, xmms_error_t *err)
{
	s4_sourcepref_t *sourcepref;
	s4_resultset_t *set;
	xmmsv_t *ret;
	xmms_fetch_info_t *info;
	xmms_fetch_spec_t *spec;

	xmms_error_reset (err);

	sourcepref = xmms_medialib_session_get_source_preferences (session);

	info = xmms_fetch_info_new (sourcepref);
	spec = xmms_fetch_spec_new (fetch, info, sourcepref, err);

	s4_sourcepref_unref (sourcepref);

	if (spec == NULL) {
		xmms_fetch_spec_free (spec);
		xmms_fetch_info_free (info);
		return NULL;
	}

	set = xmms_medialib_query_recurs (session, coll, info);
	ret = xmms_medialib_query_to_xmmsv (set, spec);
	s4_resultset_free (set);

	xmms_fetch_spec_free (spec);
	xmms_fetch_info_free (info);

	if (ret == NULL) {
		if (err) {
			xmms_error_set (err, XMMS_ERROR_NOENT, "Failed to retrieve query "
			                "result. This is probably a bug in xmms2d.");
		}
		return NULL;
	}

	xmms_medialib_session_track_garbage (session, ret);

	return ret;
}
Exemplo n.º 10
0
static void
xmms_medialib_client_rehash (xmms_medialib_t *medialib,
                             xmms_medialib_entry_t entry,
                             xmms_error_t *error)
{
	xmms_medialib_session_t *session;

	do {
		session = xmms_medialib_session_begin (medialib);
		if (xmms_medialib_check_id (session, entry)) {
			xmms_medialib_entry_status_set (session, entry, XMMS_MEDIALIB_ENTRY_STATUS_REHASH);
		} else if (entry == 0) {
			s4_sourcepref_t *sourcepref;
			s4_resultset_t *set;
			s4_val_t *status;
			gint i;

			sourcepref = xmms_medialib_session_get_source_preferences (session);

			status = s4_val_new_int (XMMS_MEDIALIB_ENTRY_STATUS_OK);
			set = xmms_medialib_filter (session, XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS,
			                            status, 0, sourcepref, "song_id", S4_FETCH_PARENT);
			s4_val_free (status);
			s4_sourcepref_unref (sourcepref);

			for (i = 0; i < s4_resultset_get_rowcount (set); i++) {
				const s4_result_t *res;

				res = s4_resultset_get_result (set, i, 0);
				for (; res != NULL; res = s4_result_next (res)) {
					xmms_medialib_entry_t item;
					s4_val_get_int (s4_result_get_val (res), &item);
					xmms_medialib_entry_status_set (session, item, XMMS_MEDIALIB_ENTRY_STATUS_REHASH);
				}
			}

			s4_resultset_free (set);
		} else {
			xmms_error_set (error, XMMS_ERROR_NOENT, "No such entry");
		}
	} while (!xmms_medialib_session_commit (session));
}
Exemplo n.º 11
0
static s4_resultset_t *
not_resolved_set (xmms_medialib_session_t *session)
{
	s4_condition_t *cond1, *cond2, *cond;
	s4_sourcepref_t *sourcepref;
	s4_fetchspec_t *spec;
	s4_resultset_t *ret;
	s4_val_t *v1, *v2;

	sourcepref = xmms_medialib_session_get_source_preferences (session);

	v1 = s4_val_new_int (XMMS_MEDIALIB_ENTRY_STATUS_NEW);
	v2 = s4_val_new_int (XMMS_MEDIALIB_ENTRY_STATUS_REHASH);

	cond1 = s4_cond_new_filter (S4_FILTER_EQUAL,
	                            XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS,
	                            v1, sourcepref, S4_CMP_CASELESS, 0);
	cond2 = s4_cond_new_filter (S4_FILTER_EQUAL,
	                            XMMS_MEDIALIB_ENTRY_PROPERTY_STATUS,
	                            v2, sourcepref, S4_CMP_CASELESS, 0);

	cond = s4_cond_new_combiner (S4_COMBINE_OR);
	s4_cond_add_operand (cond, cond1);
	s4_cond_add_operand (cond, cond2);

	spec = s4_fetchspec_create ();
	s4_fetchspec_add (spec, "song_id", sourcepref, S4_FETCH_PARENT);


	ret = xmms_medialib_session_query (session, spec, cond);

	s4_sourcepref_unref (sourcepref);
	s4_fetchspec_free (spec);
	s4_cond_free (cond);
	s4_cond_free (cond1);
	s4_cond_free (cond2);
	s4_val_free (v1);
	s4_val_free (v2);

	return ret;
}
Exemplo n.º 12
0
/**
 * Return a fresh unused medialib id.
 *
 * The first id starts at 1 as 0 is considered reserved for other use.
 */
static int32_t
xmms_medialib_get_new_id (xmms_medialib_session_t *session)
{
	gint32 highest = 0;
	s4_fetchspec_t *fs;
	s4_condition_t *cond;
	s4_resultset_t *set;
	s4_sourcepref_t *sourcepref;

	sourcepref = xmms_medialib_session_get_source_preferences (session);
	cond = s4_cond_new_custom_filter (highest_id_filter, &highest, NULL,
	                                  "song_id", sourcepref, 0, 1, S4_COND_PARENT);
	s4_sourcepref_unref (sourcepref);

	fs = s4_fetchspec_create ();
	set = xmms_medialib_session_query (session, fs, cond);

	s4_resultset_free (set);
	s4_cond_free (cond);
	s4_fetchspec_free (fs);

	return highest + 1;
}
Exemplo n.º 13
0
static s4_val_t *
xmms_medialib_entry_property_get (xmms_medialib_session_t *session,
                                  xmms_medialib_entry_t entry,
                                  const gchar *property)
{
	s4_sourcepref_t *sourcepref;
	const s4_result_t *res;
	s4_resultset_t *set;
	s4_val_t *ret = NULL;
	s4_val_t *song_id;

	g_return_val_if_fail (property, NULL);

	song_id = s4_val_new_int (entry);

	if (strcmp (property, XMMS_MEDIALIB_ENTRY_PROPERTY_ID) == 0) {
		/* only resolving attributes other than 'id' */
		return song_id;
	}

	sourcepref = xmms_medialib_session_get_source_preferences (session);

	set = xmms_medialib_filter (session, "song_id", song_id, S4_COND_PARENT,
	                            sourcepref, property, S4_FETCH_DATA);

	s4_sourcepref_unref (sourcepref);

	res = s4_resultset_get_result (set, 0, 0);
	if (res != NULL) {
		ret = s4_val_copy (s4_result_get_val (res));
	}

	s4_resultset_free (set);
	s4_val_free (song_id);

	return ret;
}
Exemplo n.º 14
0
/**
 * Decodes a cluster fetch specification from a dictionary.
 * The 'cluster-by' must be one of 'id', 'position' or 'value'. If set
 * to 'value', then an additional 'cluster-field' will be used to specify
 * which meta data attribute to cluster on.
 */
static xmms_fetch_spec_t *
xmms_fetch_spec_new_cluster (xmmsv_t *fetch, xmms_fetch_info_t *info,
                             s4_sourcepref_t *prefs, xmms_error_t *err)
{
	xmmsv_t *cluster_by, *cluster_field, *cluster_data;
	xmms_fetch_spec_t *data, *spec = NULL;
	s4_sourcepref_t *sp;
	const gchar *value = NULL;
	const gchar *field = NULL;
	const gchar *fallback = NULL;
	gint cluster_type;

	if (!xmmsv_dict_get (fetch, "cluster-by", &cluster_by)) {
		cluster_by = xmmsv_new_string ("value");
		xmmsv_dict_set (fetch, "cluster-by", cluster_by);
		xmmsv_unref (cluster_by);
	}

	if (!xmmsv_dict_entry_get_string (fetch, "cluster-by", &value)) {
		const gchar *message = "'cluster-by' must be a string.";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return NULL;
	}

	xmmsv_get_string (cluster_by, &value);

	if (!cluster_by_from_string (value, &cluster_type)) {
		const gchar *message = "'cluster-by' must be 'id', 'position', or 'value'.";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return NULL;
	}

	if (cluster_type == CLUSTER_BY_VALUE) {
		if (!xmmsv_dict_entry_get_string (fetch, "cluster-field", &field)) {
			const gchar *message = "'cluster-field' must  if 'cluster-by' is 'value'.";
			xmms_error_set (err, XMMS_ERROR_INVAL, message);
			return NULL;
		}
	}

	if (!xmmsv_dict_get (fetch, "data", &cluster_data)) {
		const gchar *message = "Required field 'data' not set in cluster.";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return NULL;
	}

	if (xmmsv_dict_entry_get_type (fetch, "cluster-fallback") == XMMSV_TYPE_NONE) {
		fallback = NULL;
	} else if (!xmmsv_dict_entry_get_string (fetch, "cluster-fallback", &fallback)) {
		const gchar *message = "Optional field 'default' must be a string.";
		xmms_error_set (err, XMMS_ERROR_INVAL, message);
		return NULL;
	}

	sp = normalize_source_preferences (fetch, prefs, err);
	if (xmms_error_iserror (err)) {
		return NULL;
	}

	data = xmms_fetch_spec_new (cluster_data, info, sp, err);
	if (xmms_error_iserror (err)) {
		s4_sourcepref_unref (sp);
		return NULL;
	}

	spec = g_new0 (xmms_fetch_spec_t, 1);
	spec->data.cluster.data = data;
	spec->data.cluster.type = cluster_type;
	spec->data.cluster.fallback = fallback;

	switch (spec->data.cluster.type) {
		case CLUSTER_BY_ID:
			spec->data.cluster.column = xmms_fetch_info_add_song_id(info, cluster_field);
			break;
		case CLUSTER_BY_VALUE:
			xmmsv_dict_get (fetch, "cluster-field", &cluster_field);
			spec->data.cluster.column = xmms_fetch_info_add_key (info, cluster_field,
			                                                     field, sp);
			break;
		case CLUSTER_BY_POSITION:
			/* do nothing */
			break;
		default:
			g_assert_not_reached ();
	}

	s4_sourcepref_unref (sp);

	return spec;
}