Commit 193cd7bd authored by Martyn James Russell's avatar Martyn James Russell

Added command line switches to faciliate the _get() and _get_multiple()

	* src/tracker-utils/tracker-info.c: Added command line switches to
	faciliate the _get() and _get_multiple() APIs for Metadata. Now we
	can request multiple specific metadata types for multiple files
	using tracker-info.

	* data/dbus/tracker-metadata.xml:
	* src/libtracker/tracker.[ch]: 
	* src/trackerd/tracker-metadata.[ch]: Added
	tracker_metadata_get_multiple() so we can get multiple metadata
	types for multiple files. This is quite a bit faster than
	requesting multiple metadata types for one file at a time. Fixes
	NB#108543.

svn path=/trunk/; revision=3160
parent ee5e3e54
2009-04-01 Martyn Russell <martyn@imendio.com>
* src/tracker-utils/tracker-info.c: Added command line switches to
faciliate the _get() and _get_multiple() APIs for Metadata. Now we
can request multiple specific metadata types for multiple files
using tracker-info.
* data/dbus/tracker-metadata.xml:
* src/libtracker/tracker.[ch]:
* src/trackerd/tracker-metadata.[ch]: Added
tracker_metadata_get_multiple() so we can get multiple metadata
types for multiple files. This is quite a bit faster than
requesting multiple metadata types for one file at a time. Fixes
NB#108543.
2009-04-01 Carlos Garnacho <carlos@imendio.com>
* src/tracker-indexer/tracker-indexer.c (mount_pre_unmount_cb): Check
......
......@@ -24,6 +24,17 @@
<arg type="aas" name="metadata" direction="out" />
</method>
<!-- Retrieves an array of metadata values for the specified array
of metadata keys for services and id pair.
-->
<method name="GetMultiple">
<annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
<arg type="s" name="service_type" direction="in" />
<arg type="as" name="uris" direction="in" />
<arg type="as" name="keys" direction="in" />
<arg type="aas" name="metadata" direction="out" />
</method>
<!-- Sets specified metadata keys to the specified metadata values
for a service and id pair.
-->
......
......@@ -441,6 +441,19 @@ tracker_metadata_get (TrackerClient *client, ServiceType service, const char *id
return array;
}
GPtrArray *
tracker_metadata_get_multiple (TrackerClient *client, ServiceType service, const char **ids, const char **keys, GError **error)
{
GPtrArray *array = NULL;
const char *service_str = tracker_service_types[service];
if (!org_freedesktop_Tracker_Metadata_get_multiple (client->proxy_metadata, service_str, ids, keys, &array, error)) {
return NULL;
}
return array;
}
GPtrArray *
tracker_metadata_get_all (TrackerClient *client, ServiceType service, const gchar *uri, GError **error)
{
......@@ -1096,6 +1109,23 @@ tracker_metadata_get_async (TrackerClient *client, ServiceType service, const ch
}
void
tracker_metadata_get_multiple_async (TrackerClient *client, ServiceType service, const char **ids, const char **keys, TrackerGPtrArrayReply callback, gpointer user_data)
{
GPtrArrayCallBackStruct *callback_struct;
const char *service_str;
callback_struct = g_new (GPtrArrayCallBackStruct, 1);
callback_struct->callback = callback;
callback_struct->data = user_data;
service_str = tracker_service_types[service];
client->last_pending_call = org_freedesktop_Tracker_Metadata_get_multiple_async (client->proxy_metadata, service_str, ids, keys, tracker_GPtrArray_reply, callback_struct);
}
void
tracker_metadata_set_async (TrackerClient *client, ServiceType service, const char *id, const char **keys, char **values, TrackerVoidReply callback, gpointer user_data)
{
......
......@@ -119,6 +119,7 @@ void tracker_shutdown (TrackerClient *client, gboolean reindex, GError **err
void tracker_prompt_index_signals (TrackerClient *client, GError **error);
char ** tracker_metadata_get (TrackerClient *client, ServiceType service, const char *id, const char **keys, GError **error);
GPtrArray * tracker_metadata_get_multiple (TrackerClient *client, ServiceType service, const char **ids, const char **keys, GError **error);
GPtrArray * tracker_metadata_get_all (TrackerClient *client, ServiceType service, const gchar *uri, GError **error);
void tracker_metadata_set (TrackerClient *client, ServiceType service, const char *id, const char **keys, char **values, GError **error);
void tracker_metadata_register_type (TrackerClient *client, const char *name, MetadataTypes type, GError **error);
......@@ -185,6 +186,7 @@ void tracker_shutdown_async (TrackerClient *client, gboolean reindex, Track
void tracker_prompt_index_signals_async (TrackerClient *client, TrackerVoidReply callback, gpointer user_data);
void tracker_metadata_get_async (TrackerClient *client, ServiceType service, const char *id, const char **keys, TrackerArrayReply callback, gpointer user_data);
void tracker_metadata_get_multiple_async (TrackerClient *client, ServiceType service, const char **ids, const char **keys, TrackerGPtrArrayReply callback, gpointer user_data);
void tracker_metadata_set_async (TrackerClient *client, ServiceType service, const char *id, const char **keys, char **values, TrackerVoidReply callback, gpointer user_data);
void tracker_metadata_register_type_async (TrackerClient *client, const char *name, MetadataTypes type, TrackerVoidReply callback, gpointer user_data);
void tracker_metadata_get_registered_types_async (TrackerClient *client, const char *classname, TrackerArrayReply callback, gpointer user_data);
......
......@@ -34,28 +34,55 @@
#include <libtracker-common/tracker-common.h>
static gchar *service;
static gchar **uri = NULL;
static gchar **metadata;
static gchar **uris;
static GOptionEntry entries[] = {
{ "service", 's', 0, G_OPTION_ARG_STRING, &service,
N_("Service type of the file"),
NULL
N_("Files")
},
{ G_OPTION_REMAINING, 0,
G_OPTION_FLAG_FILENAME, G_OPTION_ARG_STRING_ARRAY, &uri,
{ "metadata", 'm', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_STRING_ARRAY, &metadata,
N_("Metadata to request (optional, multiple calls allowed)"),
N_("File:Size")
},
{ G_OPTION_REMAINING, 0, G_OPTION_FLAG_FILENAME, G_OPTION_ARG_FILENAME_ARRAY, &uris,
N_("FILE..."),
N_("FILE")},
N_("FILE")
},
{ NULL }
};
static void
print_property_value (gpointer value)
print_property_value (gpointer data,
gpointer user_data)
{
gchar **pair;
GStrv results;
GStrv uris_used;
results = data;
uris_used = user_data;
pair = value;
if (uris_used) {
static gint uri_id = 0;
GStrv p;
gint i;
g_print (" '%s' = '%s'\n", pair[0], pair[1]);
g_print ("%s\n", uris_used[uri_id]);
if (!results) {
g_print (" %s\n", _("No metadata available"));
return;
}
for (p = results, i = 0; *p; p++, i++) {
g_print (" '%s' = '%s'\n", metadata[i], *p);
}
uri_id++;
} else {
g_print (" '%s' = '%s'\n", results[0], results[1]);
}
}
int
......@@ -64,10 +91,13 @@ main (int argc, char **argv)
TrackerClient *client;
ServiceType type;
GFile *file;
gchar *abs_path;
gchar *summary;
gchar *path;
GOptionContext *context;
GError *error = NULL;
GPtrArray *results;
guint count;
gint i;
gint exit_result = EXIT_SUCCESS;
setlocale (LC_ALL, "");
......@@ -81,14 +111,34 @@ main (int argc, char **argv)
/* Translators: this message will appear after the usage string */
/* and before the list of options. */
summary = g_strconcat (_("For a list of services and metadata that "
"can be used here, see tracker-services."),
NULL);
g_option_context_set_summary (context, summary);
g_option_context_add_main_entries (context, entries, NULL);
g_option_context_parse (context, &argc, &argv, NULL);
g_free (summary);
if (!uri) {
if (!uris) {
gchar *help;
g_printerr ("%s\n\n",
_("Uri missing"));
g_printerr (_("URI missing"));
g_printerr ("\n\n");
help = g_option_context_get_help (context, TRUE, NULL);
g_option_context_free (context);
g_printerr ("%s", help);
g_free (help);
return EXIT_FAILURE;
}
if (!metadata && g_strv_length (uris) > 1) {
gchar *help;
g_printerr (_("Requesting ALL information about multiple files is not supported"));
g_printerr ("\n\n");
help = g_option_context_get_help (context, TRUE, NULL);
g_option_context_free (context);
......@@ -103,67 +153,154 @@ main (int argc, char **argv)
client = tracker_connect (FALSE);
if (!client) {
g_printerr ("%s\n",
_("Could not establish a DBus connection to Tracker"));
g_printerr (_("Could not establish a DBus connection to Tracker"));
g_printerr ("\n");
return EXIT_FAILURE;
}
if (!service) {
g_print ("%s\n",
_("Defaulting to 'files' service"));
g_print (_("Defaulting to 'files' service"));
g_print ("\n");
type = SERVICE_FILES;
} else {
type = tracker_service_name_to_type (service);
if (type == SERVICE_OTHER_FILES && g_ascii_strcasecmp (service, "Other")) {
g_printerr ("%s\n",
_("Service type not recognized, using 'Other' ..."));
g_printerr (_("Service type not recognized, using 'Other' ..."));
g_printerr ("\n");
}
}
file = g_file_new_for_commandline_arg (uri[0]);
abs_path = g_file_get_path (file);
count = g_strv_length (uris);
results = tracker_metadata_get_all (client,
if (count > 1 && metadata != NULL) {
gchar **strv;
GPtrArray *results;
strv = g_new (gchar*, count + 1);
/* Convert all files to real paths */
for (i = 0; i < count; i++) {
file = g_file_new_for_commandline_arg (uris[i]);
path = g_file_get_path (file);
g_object_unref (file);
strv[i] = path;
}
strv[i] = NULL;
results = tracker_metadata_get_multiple (client,
type,
abs_path,
(const gchar **) strv,
(const gchar **) metadata,
&error);
g_free (abs_path);
g_object_unref (file);
if (error) {
g_printerr ("%s, %s\n",
_("Unable to retrieve data for uri"),
g_printerr (_("Unable to retrieve data for %d uris"),
count);
g_printerr (", %s\n",
error->message);
g_error_free (error);
tracker_disconnect (client);
return EXIT_FAILURE;
exit_result = EXIT_FAILURE;
} else if (!results) {
g_print (_("No metadata available for all %d uris"),
count);
g_print ("\n");
} else {
g_print (_("Results:"));
g_print ("\n");
g_ptr_array_foreach (results, print_property_value, strv);
g_ptr_array_foreach (results, (GFunc) g_strfreev, NULL);
g_ptr_array_free (results, TRUE);
}
if (!results) {
g_print ("%s\n",
_("No metadata available for that uri"));
g_strfreev (strv);
} else {
GPtrArray *results;
file = g_file_new_for_commandline_arg (uris[0]);
path = g_file_get_path (file);
if (G_LIKELY (!metadata)) {
results = tracker_metadata_get_all (client,
type,
path,
&error);
if (error) {
g_printerr ("%s, %s\n",
_("Unable to retrieve data for uri"),
error->message);
g_error_free (error);
exit_result = EXIT_FAILURE;
} else if (!results) {
g_print (_("No metadata available for that uri"));
g_print ("\n");
} else {
gint length;
length = results->len;
g_print (tracker_dngettext (NULL,
_("Result: %d"),
_("Results: %d"),
_("Result: %d for '%s'"),
_("Results: %d for '%s'"),
length),
length);
length,
path);
g_print ("\n");
g_ptr_array_foreach (results, (GFunc) print_property_value, NULL);
g_ptr_array_foreach (results, print_property_value, NULL);
g_ptr_array_foreach (results, (GFunc) g_strfreev, NULL);
g_ptr_array_free (results, TRUE);
}
} else {
GStrv results;
results = tracker_metadata_get (client,
type,
path,
(const gchar **) metadata,
&error);
if (error) {
g_printerr ("%s, %s\n",
_("Unable to retrieve data for uri"),
error->message);
g_error_free (error);
exit_result = EXIT_FAILURE;
} else if (!results) {
g_print (_("No metadata available for that uri"));
g_print ("\n");
} else {
gint length;
gint i;
length = g_strv_length (results);
g_print (_("Results:"));
g_print ("\n");
for (i = 0; i < length; i++) {
g_print (" '%s' = '%s'\n",
metadata[i], results[i]);
}
g_strfreev (results);
}
}
g_object_unref (file);
g_free (path);
}
tracker_disconnect (client);
return EXIT_SUCCESS;
return exit_result;
}
......@@ -65,88 +65,62 @@ tracker_metadata_new (void)
* Functions
*/
void
tracker_metadata_get (TrackerMetadata *object,
static gchar **
tracker_metadata_get_internal (TrackerMetadata *object,
guint request_id,
const gchar *service_type,
const gchar *uri,
gchar **keys,
DBusGMethodInvocation *context,
GError **error)
{
TrackerDBInterface *iface;
TrackerDBResultSet *result_set;
guint request_id;
const gchar *service_result;
guint32 service_id;
gchar *service_id_str;
guint i;
gchar **values;
GError *actual_error = NULL;
request_id = tracker_dbus_get_next_request_id ();
tracker_dbus_async_return_if_fail (service_type != NULL, context);
tracker_dbus_async_return_if_fail (uri != NULL, context);
tracker_dbus_async_return_if_fail (keys != NULL, context);
tracker_dbus_async_return_if_fail (g_strv_length (keys) > 0, context);
tracker_dbus_request_new (request_id,
"DBus request to get metadata values, "
"service type:'%s'",
service_type);
if (!tracker_ontology_service_is_valid (service_type)) {
tracker_dbus_request_failed (request_id,
&actual_error,
error,
"Service '%s' is invalid or has not been implemented yet",
service_type);
dbus_g_method_return_error (context, actual_error);
g_error_free (actual_error);
return;
return NULL;
}
service_id = tracker_data_query_file_id (service_type, uri);
if (service_id <= 0) {
tracker_dbus_request_failed (request_id,
&actual_error,
error,
"Service URI '%s' not found",
uri);
dbus_g_method_return_error (context, actual_error);
g_error_free (actual_error);
return;
return NULL;
}
/* Checking keys */
for (i = 0; i < g_strv_length (keys); i++) {
if (tracker_ontology_get_field_by_name (keys[i]) == NULL) {
tracker_dbus_request_failed (request_id,
&actual_error,
error,
"Metadata field '%s' not registered in the system",
keys[i]);
dbus_g_method_return_error (context, actual_error);
g_error_free (actual_error);
return;
return NULL;
}
}
/* The parameter service_type can be "Files"
* and the actual service type of the uri "Video"
*
* Note: Does this matter?
*/
/* Get database interface */
iface = tracker_db_manager_get_db_interface_by_service (service_type);
/* Check we have a file in the database before looking up the metadata. */
service_result = tracker_data_query_service_type_by_id (iface, service_id);
if (!service_result) {
tracker_dbus_request_failed (request_id,
&actual_error,
error,
"Service type can not be found for entity '%s'",
uri);
dbus_g_method_return_error (context, actual_error);
g_error_free (actual_error);
return;
return NULL;
}
service_id_str = tracker_guint_to_string (service_id);
......@@ -162,10 +136,49 @@ tracker_metadata_get (TrackerMetadata *object,
if (!values) {
tracker_dbus_request_failed (request_id,
&actual_error,
error,
"No metadata information was available");
return NULL;
}
return values;
}
void
tracker_metadata_get (TrackerMetadata *object,
const gchar *service_type,
const gchar *uri,
gchar **keys,
DBusGMethodInvocation *context,
GError **error)
{
guint request_id;
gchar **values;
GError *actual_error = NULL;
request_id = tracker_dbus_get_next_request_id ();
tracker_dbus_async_return_if_fail (service_type != NULL, context);
tracker_dbus_async_return_if_fail (uri != NULL, context);
tracker_dbus_async_return_if_fail (keys != NULL, context);
tracker_dbus_async_return_if_fail (g_strv_length (keys) > 0, context);
tracker_dbus_request_new (request_id,
"DBus request to get metadata values, "
"service type:'%s'",
service_type);
values = tracker_metadata_get_internal (object,
request_id,
service_type,
uri,
keys,
&actual_error);
if (!values) {
dbus_g_method_return_error (context, actual_error);
g_error_free (actual_error);
return;
}
dbus_g_method_return (context, values);
......@@ -174,6 +187,61 @@ tracker_metadata_get (TrackerMetadata *object,
tracker_dbus_request_success (request_id);
}
void
tracker_metadata_get_multiple (TrackerMetadata *object,
const gchar *service_type,
const gchar **uris,
gchar **keys,
DBusGMethodInvocation *context,
GError **error)
{
guint request_id;
guint count;
gint i;
GPtrArray *values;
GError *actual_error = NULL;
request_id = tracker_dbus_get_next_request_id ();
tracker_dbus_async_return_if_fail (service_type != NULL, context);
tracker_dbus_async_return_if_fail (uris != NULL, context);
tracker_dbus_async_return_if_fail (keys != NULL, context);
tracker_dbus_async_return_if_fail (g_strv_length (keys) > 0, context);
tracker_dbus_request_new (request_id,
"DBus request to get multiple metadata values, "
"service type:'%s'",
service_type);
count = g_strv_length ((GStrv) uris);
values = g_ptr_array_sized_new (count);
for (i = 0; i < count && !actual_error; i++) {
GStrv strv;
strv = tracker_metadata_get_internal (object,
request_id,
service_type,
uris[i],
keys,
&actual_error);
/* Don't allow errors, but allow NULLs */
g_ptr_array_add (values, strv);
}
if (G_UNLIKELY (actual_error)) {
dbus_g_method_return_error (context, actual_error);
g_error_free (actual_error);
} else {
dbus_g_method_return (context, values);
tracker_dbus_request_success (request_id);
}
g_ptr_array_foreach (values, (GFunc) g_strfreev, NULL);
g_ptr_array_free (values, TRUE);
}
void
tracker_metadata_get_all (TrackerMetadata *object,
const gchar *service_type,
......
......@@ -63,6 +63,12 @@ void tracker_metadata_get_all (TrackerMetadata *obje
const gchar *uri,
DBusGMethodInvocation *context,
GError **error);
void tracker_metadata_get_multiple (TrackerMetadata *object,
const gchar *service_type,
const gchar **uris,
gchar **keys,
DBusGMethodInvocation *context,
GError **error);
void tracker_metadata_set (TrackerMetadata *object,
const gchar *service_type,
const gchar *uri,
......@@ -102,7 +108,6 @@ void tracker_metadata_get_count (TrackerMetadata *object,
const gchar *query_condition,
DBusGMethodInvocation *context,
GError **error);
void tracker_metadata_get_unique_values_with_count (TrackerMetadata *object,
const gchar *service_type,
gchar **fields,
......@@ -113,7 +118,6 @@ void tracker_metadata_get_unique_values_with_count (TrackerMetadata
gint max_hits,
DBusGMethodInvocation *context,
GError **error);
void tracker_metadata_get_unique_values_with_count_and_sum (TrackerMetadata *object,
const gchar *service_type,
gchar **fields,
......@@ -125,7 +129,6 @@ void tracker_metadata_get_unique_values_with_count_and_sum (TrackerMetadata
gint max_hits,
DBusGMethodInvocation *context,
GError **error);
void tracker_metadata_get_unique_values_with_concat_count_and_sum (TrackerMetadata *object,
const gchar *service_type,
gchar **fields,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment