Beispiel #1
0
void
xmms_medialib_entry_cleanup (xmms_medialib_session_t *session,
                             xmms_medialib_entry_t entry)
{
	s4_resultset_t *set;
	s4_val_t *song_id;
	gint i;

	song_id = s4_val_new_int (entry);

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


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

		res = s4_resultset_get_result (set, i, 0);
		while (res != NULL) {
			const gchar *src = s4_result_get_src (res);
			const gchar *key = s4_result_get_key (res);

			if (entry_attribute_is_derived (src, key)) {
				const s4_val_t *value = s4_result_get_val (res);
				xmms_medialib_session_property_unset (session, entry, key,
				                                      value, src);
			}

			res = s4_result_next (res);
		}
	}

	s4_resultset_free (set);
	s4_val_free (song_id);
}
Beispiel #2
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;
}
Beispiel #3
0
/**
 * Remove a medialib entry from the database
 *
 * @param id_num Entry to remove
 */
void
xmms_medialib_entry_remove (xmms_medialib_session_t *session,
                            xmms_medialib_entry_t entry)
{
	s4_resultset_t *set;
	s4_val_t *song_id;
	gint i;

	song_id = s4_val_new_int (entry);

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

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

		res = s4_resultset_get_result (set, i, 0);
		while (res != NULL) {
			xmms_medialib_session_property_unset (session, entry,
			                                      s4_result_get_key (res),
			                                      s4_result_get_val (res),
			                                      s4_result_get_src (res));
			res = s4_result_next (res);
		}
	}

	s4_resultset_free (set);
	s4_val_free (song_id);
}
Beispiel #4
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);
}
Beispiel #5
0
Datei: t_s4.c Projekt: xmms2/s4
static void check_result (const s4_result_t *res, const char *key, const char *val, const char *src)
{
	const char *str;
	CU_ASSERT (s4_val_get_str (s4_result_get_val (res), &str));
	CU_ASSERT (!strcmp (s4_result_get_key (res), key));
	CU_ASSERT (!strcmp (str, val));
	CU_ASSERT (!strcmp (s4_result_get_src (res), src));
}
Beispiel #6
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;
}
Beispiel #7
0
static xmmsv_t *
xmms_medialib_entry_to_tree (xmms_medialib_session_t *session,
                             xmms_medialib_entry_t entry)
{
	s4_resultset_t *set;
	s4_val_t *song_id;
	xmmsv_t *ret, *id;
	gint i;

	song_id = s4_val_new_int (entry);
	set = xmms_medialib_filter (session, "song_id", song_id, S4_COND_PARENT,
	                            NULL, NULL, S4_FETCH_PARENT | S4_FETCH_DATA);
	s4_val_free (song_id);

	ret = xmmsv_new_dict ();

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

		res = s4_resultset_get_result (set, 0, 0);
		while (res != NULL) {
			xmmsv_t *v_entry = NULL;
			const s4_val_t *val;
			const char *s;
			gint32 i;

			val = s4_result_get_val (res);
			if (s4_val_get_str (val, &s)) {
				v_entry = xmmsv_new_string (s);
			} else if (s4_val_get_int (val, &i)) {
				v_entry = xmmsv_new_int (i);
			}

			xmms_medialib_tree_add_tuple (ret, s4_result_get_key (res),
			                              s4_result_get_src (res), v_entry);
			xmmsv_unref (v_entry);

			res = s4_result_next (res);
		}
	}

	s4_resultset_free (set);

	id = xmmsv_new_int (entry);
	xmms_medialib_tree_add_tuple (ret, "id", "server", id);
	xmmsv_unref (id);

	return ret;
}
Beispiel #8
0
xmms_medialib_entry_t
xmms_medialib_entry_not_resolved_get (xmms_medialib_session_t *session)
{
	const s4_result_t *res;
	s4_resultset_t *set;
	gint32 ret = 0;

	set = not_resolved_set (session);
	res = s4_resultset_get_result (set, 0, 0);

	if (res != NULL) {
		s4_val_get_int (s4_result_get_val (res), &ret);
	}

	s4_resultset_free (set);

	return ret;
}
/* Divides an S4 set into a list of smaller sets with
 * the same values for the cluster attributes
 */
static void
cluster_set (s4_resultset_t *set, xmms_fetch_spec_t *spec,
             GHashTable *table, GList **list)
{
	const s4_resultrow_t *row;
	gint position;

	/* Run through all the rows in the result set.
	 * Uses a hash table to find the correct cluster to put the row in
	 */
	for (position = 0; s4_resultset_get_row (set, position, &row); position++) {
		s4_resultset_t *cluster;
		const s4_result_t *res;
		const gchar *value = spec->data.cluster.fallback;
		gchar buf[12];

		if (spec->data.cluster.type == CLUSTER_BY_POSITION) {
			g_snprintf (buf, sizeof (buf), "%i", position);
			value = buf;
		} else if (s4_resultrow_get_col (row, spec->data.cluster.column, &res)) {
			const s4_val_t *val = s4_result_get_val (res);
			if (!s4_val_get_str (val, &value)) {
				gint32 ival;
				s4_val_get_int (val, &ival);
				g_snprintf (buf, sizeof (buf), "%i", ival);
				value = buf;
			}
		}

		if (value == NULL) {
			/* value not found, and no fallback provided */
			continue;
		}

		cluster = g_hash_table_lookup (table, value);
		if (cluster == NULL) {
			cluster = s4_resultset_create (s4_resultset_get_colcount (set));
			g_hash_table_insert (table, g_strdup (value), cluster);
			*list = g_list_prepend (*list, cluster);
		}
		s4_resultset_add_row (cluster, row);
	}
}
Beispiel #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));
}
Beispiel #11
0
Datei: t_s4.c Projekt: xmms2/s4
static void check_db (struct db_struct *db)
{
	int i, j;
	s4_fetchspec_t *fs = s4_fetchspec_create ();
	s4_fetchspec_add (fs, NULL, NULL, S4_FETCH_DATA);

	for (i = 0; db[i].name != NULL; i++) {
		s4_val_t *name_val = s4_val_new_string (db[i].name);
		s4_condition_t *cond = s4_cond_new_filter (S4_FILTER_EQUAL,
				"entry", name_val, NULL, S4_CMP_CASELESS, S4_COND_PARENT);
		s4_transaction_t *trans = s4_begin (s4, 0);
		s4_resultset_t *set = s4_query (trans, fs, cond);
		s4_commit (trans);
		const s4_result_t *res = s4_resultset_get_result (set, 0, 0);
		int found[ARG_SIZE] = {0};

		for (; res != NULL; res = s4_result_next (res)) {
			for (j = 0; db[i].args[j] != NULL; j++) {
				const char *str;

				if (s4_val_get_str (s4_result_get_val (res), &str) && !strcmp (str, db[i].args[j]) &&
						!strcmp (s4_result_get_key (res), "property") &&
						!strcmp (s4_result_get_src (res), db[i].src)) {
					found[j] = 1;
					break;
				}
			}
		}
		for (j = 0; db[i].args[j] != NULL; j++) {
			CU_ASSERT_EQUAL (found[j], 1);
		}

		s4_resultset_free (set);
		s4_cond_free (cond);
		s4_val_free (name_val);
	}

	s4_fetchspec_free (fs);
}
Beispiel #12
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;
}
/* Converts an S4 resultset to an xmmsv using the fetch specification */
static xmmsv_t *
metadata_to_xmmsv (s4_resultset_t *set, xmms_fetch_spec_t *spec)
{
	const s4_resultrow_t *row;
	xmmsv_t *ret = NULL;
	gint i;

	/* Loop over the rows in the resultset */
	for (i = 0; s4_resultset_get_row (set, i, &row); i++) {
		gint32 id, j;

		s4_val_get_int (s4_result_get_val (s4_resultset_get_result (set, i, 0)), &id);
		for (j = 0; j < spec->data.metadata.col_count; j++) {
			const s4_result_t *res;

			if (s4_resultrow_get_col (row, spec->data.metadata.cols[j], &res)) {
				ret = result_to_xmmsv (ret, id, res, spec);
			}
		}
	}

	return aggregate_result (ret, spec->data.metadata.get_size - 1,
	                         spec->data.metadata.aggr_func);
}
/* Converts an S4 result (a column) into an xmmsv values */
static void *
result_to_xmmsv (xmmsv_t *ret, gint32 id, const s4_result_t *res,
                 xmms_fetch_spec_t *spec)
{
	static xmmsv_t * (*aggregate_functions[AGGREGATE_END])(xmmsv_t *c, gint i, const gchar *s) = {
		aggregate_first,
		aggregate_sum,
		aggregate_max,
		aggregate_min,
		aggregate_set,
		aggregate_list,
		aggregate_random,
		aggregate_average
	};
	const s4_val_t *val;
	xmmsv_t *dict, *current;
	const gchar *str_value, *key = NULL;
	gint32 i, int_value;
	xmmsv_t *newval;

	g_return_val_if_fail (spec->data.metadata.get_size > 0, ret);
	g_return_val_if_fail (spec->data.metadata.get_size <= METADATA_END, ret);
	g_return_val_if_fail (spec->data.metadata.aggr_func >= 0, ret);
	g_return_val_if_fail (spec->data.metadata.aggr_func < AGGREGATE_END, ret);

	/* Loop through all the values the column has */
	while (res != NULL) {
		dict = ret;
		current = ret;

		/* Loop through the list of what to get ("key", "source", ..) */
		for (i = 0; i < spec->data.metadata.get_size; i++) {
			str_value = NULL;
			int_value = 0;

			/* Fill str_value with the correct value if it is a string
			 * or int_value if it is an integer
			 */
			switch (spec->data.metadata.get[i]) {
				case METADATA_KEY:
					str_value = s4_result_get_key (res);
					break;
				case METADATA_SOURCE:
					str_value = s4_result_get_src (res);
					if (str_value == NULL)
						str_value = "server";
					break;
				case METADATA_ID:
					int_value = id;
					break;
				case METADATA_VALUE:
					val = s4_result_get_val (res);

					if (!s4_val_get_int (val, &int_value)) {
						s4_val_get_str (val, &str_value);
					}
					break;
				default:
					g_assert_not_reached ();
			}

			/* If this is not the last property to get we use this property
			 * as a key in a dict
			 */
			if (i < (spec->data.metadata.get_size - 1)) {
				/* Convert integers to strings */
				if (str_value == NULL) {
					/* Big enough to hold 2^32 with minus sign */
					gchar buf[12];
					g_sprintf (buf, "%i", int_value);
					key = buf;
				} else {
					key = str_value;
				}

				/* Make sure the root dict exists */
				if (dict == NULL) {
					ret = dict = xmmsv_new_dict ();
				}

				/* If this dict contains dicts we have to create a new
				 * dict if one does not exists for the key yet
				 */
				if (!xmmsv_dict_get (dict, key, &current))
					current = NULL;

				if (i < (spec->data.metadata.get_size - 2)) {
					if (current == NULL) {
						current = xmmsv_new_dict ();
						xmmsv_dict_set (dict, key, current);
						xmmsv_unref (current);
					}
					dict = current;
				}
			}
		}

		newval = aggregate_functions[spec->data.metadata.aggr_func](current, int_value, str_value);

		/* Update the previous dict (if there is one) */
		if (newval != current) {
			if (i > 1) {
				xmmsv_dict_set (dict, key, newval);
				xmmsv_unref (newval);
			} else {
				ret = newval;
				if (current != NULL) {
					xmmsv_unref (current);
				}
			}
		}

		res = s4_result_next (res);
	}

	return ret;
}