tracker r2975 - in trunk: . data/db data/dbus src/libtracker src/libtracker-data src/tracker-utils src/trackerd
- From: mottela svn gnome org
- To: svn-commits-list gnome org
- Subject: tracker r2975 - in trunk: . data/db data/dbus src/libtracker src/libtracker-data src/tracker-utils src/trackerd
- Date: Wed, 25 Feb 2009 17:38:56 +0000 (UTC)
Author: mottela
Date: Wed Feb 25 17:38:56 2009
New Revision: 2975
URL: http://svn.gnome.org/viewvc/tracker?rev=2975&view=rev
Log:
Added method to dbus API for concatenating fields in groupings and fixed some order field joining issues
Modified:
trunk/ChangeLog
trunk/data/db/sqlite-service.sql
trunk/data/dbus/tracker-metadata.xml
trunk/src/libtracker-data/tracker-data-schema.c
trunk/src/libtracker-data/tracker-data-search.c
trunk/src/libtracker-data/tracker-data-search.h
trunk/src/libtracker-data/tracker-rdf-query.c
trunk/src/libtracker/tracker.c
trunk/src/libtracker/tracker.h
trunk/src/tracker-utils/tracker-unique.c
trunk/src/trackerd/tracker-metadata.c
trunk/src/trackerd/tracker-metadata.h
Modified: trunk/data/db/sqlite-service.sql
==============================================================================
--- trunk/data/db/sqlite-service.sql (original)
+++ trunk/data/db/sqlite-service.sql Wed Feb 25 17:38:56 2009
@@ -61,7 +61,7 @@
MetaDataCollation Text
);
-CREATE INDEX ServiceMetaDataCompoundIndex ON ServiceMetaData (ServiceID, MetaDataID, MetaDataDisplay);
+CREATE INDEX ServiceMetaDataCompoundIndex ON ServiceMetaData (ServiceID, MetaDataID, MetaDataDisplay, MetaDataCollation);
/* metadata for all keyword types - keywords are db indexed for fast searching - they are also not processed like other metadata. */
CREATE TABLE ServiceKeywordMetaData
Modified: trunk/data/dbus/tracker-metadata.xml
==============================================================================
--- trunk/data/dbus/tracker-metadata.xml (original)
+++ trunk/data/dbus/tracker-metadata.xml Wed Feb 25 17:38:56 2009
@@ -119,5 +119,19 @@
<arg type="aas" name="result" direction="out" />
</method>
+ <method name="GetUniqueValuesWithConcatCountAndSum">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+ <arg type="s" name="service" direction="in" />
+ <arg type="as" name="meta_types" direction="in" />
+ <arg type="s" name="query" direction="in" />
+ <arg type="s" name="concat_field" direction="in" />
+ <arg type="s" name="count_field" direction="in" />
+ <arg type="s" name="sum_field" direction="in" />
+ <arg type="b" name="descending" direction="in" />
+ <arg type="i" name="offset" direction="in" />
+ <arg type="i" name="max_hits" direction="in" />
+ <arg type="aas" name="result" direction="out" />
+ </method>
+
</interface>
</node>
Modified: trunk/src/libtracker-data/tracker-data-schema.c
==============================================================================
--- trunk/src/libtracker-data/tracker-data-schema.c (original)
+++ trunk/src/libtracker-data/tracker-data-schema.c Wed Feb 25 17:38:56 2009
@@ -279,7 +279,6 @@
(tracker_field_get_data_type (def) == TRACKER_FIELD_TYPE_INDEX) ||
(tracker_field_get_data_type (def) == TRACKER_FIELD_TYPE_STRING)) {
order_field = g_strdup_printf ("M%d.MetaDataCollation", field_count);
- tracker_field_data_set_needs_join (field_data, TRUE);
} else {
order_field = g_strdup_printf ("M%d.MetaDataValue", field_count);
}
Modified: trunk/src/libtracker-data/tracker-data-search.c
==============================================================================
--- trunk/src/libtracker-data/tracker-data-search.c (original)
+++ trunk/src/libtracker-data/tracker-data-search.c Wed Feb 25 17:38:56 2009
@@ -664,6 +664,14 @@
type == TRACKER_FIELD_TYPE_DOUBLE;
}
+static gboolean
+is_data_type_text (TrackerFieldType type)
+{
+ return
+ type == TRACKER_FIELD_TYPE_STRING ||
+ type == TRACKER_FIELD_TYPE_INDEX;
+}
+
static TrackerFieldData *
tracker_metadata_add_metadata_field (TrackerDBInterface *iface,
const gchar *service,
@@ -788,7 +796,7 @@
g_string_append_printf (sql_select, "COALESCE(%s,'')", tracker_field_data_get_select_field (fd));
g_string_append_printf (sql_order, " %s %s",
- tracker_field_data_get_order_field (fd),
+ tracker_field_data_get_select_field (fd),
order_desc ? "DESC" : "ASC" );
}
@@ -914,7 +922,7 @@
g_string_append_printf (sql_select, "COALESCE(%s,'')", tracker_field_data_get_select_field (fd));
g_string_append_printf (sql_order, " %s %s",
- tracker_field_data_get_order_field (fd),
+ tracker_field_data_get_select_field (fd),
order_desc ? "DESC" : "ASC" );
g_string_append_printf (sql_group, "COALESCE(%s,'')", tracker_field_data_get_select_field (fd));
@@ -1074,12 +1082,247 @@
g_string_append_printf (sql_select, "COALESCE(%s,'')", tracker_field_data_get_select_field (fd));
g_string_append_printf (sql_order, " %s %s",
- tracker_field_data_get_order_field (fd),
+ tracker_field_data_get_select_field (fd),
+ order_desc ? "DESC" : "ASC" );
+ g_string_append_printf (sql_group, "COALESCE(%s,'')", tracker_field_data_get_select_field (fd));
+
+ }
+
+ if (count_field && !(tracker_is_empty_string (count_field))) {
+ TrackerFieldData *fd;
+
+ if (strcmp (count_field, "*")) {
+ fd = tracker_metadata_add_metadata_field (iface, service_type, &field_list, count_field, TRUE, FALSE);
+
+ if (!fd) {
+ g_string_free (sql_select, TRUE);
+ g_string_free (sql_from, TRUE);
+ g_string_free (sql_where, TRUE);
+ g_string_free (sql_order, TRUE);
+ g_string_free (sql_group, TRUE);
+
+ g_set_error (error, TRACKER_DBUS_ERROR, 0,
+ "Invalid or non-existant metadata type '%s' specified",
+ count_field);
+ return NULL;
+ }
+
+ g_string_append_printf (sql_select, ", COUNT (DISTINCT COALESCE(%s,''))", tracker_field_data_get_select_field (fd));
+ } else {
+ g_string_append_printf (sql_select, ", COUNT (DISTINCT S.ID)");
+ }
+ }
+
+ if (sum_field && !(tracker_is_empty_string (sum_field))) {
+ TrackerFieldData *fd;
+ TrackerFieldType data_type;
+
+ fd = tracker_metadata_add_metadata_field (iface, service_type, &field_list, sum_field, TRUE, FALSE);
+
+ if (!fd) {
+ g_string_free (sql_select, TRUE);
+ g_string_free (sql_from, TRUE);
+ g_string_free (sql_where, TRUE);
+ g_string_free (sql_order, TRUE);
+ g_string_free (sql_group, TRUE);
+
+ g_set_error (error, TRACKER_DBUS_ERROR, 0,
+ "Invalid or non-existant metadata type '%s' specified",
+ sum_field);
+ return NULL;
+ }
+
+ data_type = tracker_field_data_get_data_type (fd);
+
+ if (!is_data_type_numeric (data_type)) {
+ g_string_free (sql_select, TRUE);
+ g_string_free (sql_from, TRUE);
+ g_string_free (sql_where, TRUE);
+ g_string_free (sql_order, TRUE);
+ g_string_free (sql_group, TRUE);
+
+ g_set_error (error, TRACKER_DBUS_ERROR, 0,
+ "Cannot sum '%s': this metadata type is not numeric",
+ sum_field);
+ return NULL;
+ }
+
+ g_string_append_printf (sql_select, ", SUM (%s)", tracker_field_data_get_select_field (fd));
+ }
+
+ tracker_rdf_filter_to_sql (iface, query_condition, service_type,
+ &field_list, &rdf_from, &rdf_where, &actual_error);
+
+ if (actual_error) {
+ g_string_free (sql_select, TRUE);
+ g_string_free (sql_from, TRUE);
+ g_string_free (sql_where, TRUE);
+ g_string_free (sql_order, TRUE);
+ g_string_free (sql_group, TRUE);
+
+ g_propagate_error (error, actual_error);
+
+ return NULL;
+ }
+
+ g_string_append_printf (sql_from, " %s ", rdf_from);
+ g_string_append_printf (sql_where, " %s ", rdf_where);
+
+ g_free (rdf_from);
+ g_free (rdf_where);
+
+ str_offset = tracker_gint_to_string (offset);
+ str_limit = tracker_gint_to_string (metadata_sanity_check_max_hits (max_hits));
+
+ g_string_append_printf (sql_order, " LIMIT %s,%s", str_offset, str_limit);
+
+ sql = g_strconcat (sql_select->str, " ",
+ sql_from->str, " ",
+ sql_where->str, " ",
+ sql_group->str, " ",
+ sql_order->str, NULL);
+
+ g_free (str_offset);
+ g_free (str_limit);
+
+ g_string_free (sql_select, TRUE);
+ g_string_free (sql_from, TRUE);
+ g_string_free (sql_where, TRUE);
+ g_string_free (sql_order, TRUE);
+ g_string_free (sql_group, TRUE);
+
+ g_slist_foreach (field_list, (GFunc) g_object_unref, NULL);
+ g_slist_free (field_list);
+
+ g_message ("Unique values query executed:\n%s", sql);
+
+ result_set = tracker_db_interface_execute_query (iface, NULL, "%s", sql);
+
+ g_free (sql);
+
+ return result_set;
+}
+
+TrackerDBResultSet *
+tracker_data_search_get_unique_values_with_concat_count_and_sum (const gchar *service_type,
+ gchar **fields,
+ const gchar *query_condition,
+ const gchar *concat_field,
+ const gchar *count_field,
+ const gchar *sum_field,
+ gboolean order_desc,
+ gint offset,
+ gint max_hits,
+ GError **error)
+{
+ TrackerDBInterface *iface;
+ TrackerDBResultSet *result_set = NULL;
+
+ GSList *field_list = NULL;
+ gchar *str_offset, *str_limit;
+
+ GString *sql_select;
+ GString *sql_from;
+ GString *sql_where;
+ GString *sql_order;
+ GString *sql_group;
+ gchar *sql;
+
+ gchar *rdf_where;
+ gchar *rdf_from;
+ GError *actual_error = NULL;
+
+ guint i;
+
+ g_return_val_if_fail (service_type != NULL, NULL);
+ g_return_val_if_fail (fields != NULL, NULL);
+ g_return_val_if_fail (query_condition != NULL, NULL);
+
+ if (!tracker_ontology_service_is_valid (service_type)) {
+ g_set_error (error, TRACKER_DBUS_ERROR, 0,
+ "Service_Type '%s' is invalid or has not been implemented yet",
+ service_type);
+ return NULL;
+ }
+
+ iface = tracker_db_manager_get_db_interface_by_service (service_type);
+
+ sql_select = g_string_new ("SELECT DISTINCT ");
+ sql_from = g_string_new ("\nFROM Services AS S ");
+ sql_where = g_string_new ("\nWHERE ");
+ sql_order = g_string_new ("\nORDER BY ");
+ sql_group = g_string_new ("\nGROUP BY ");
+
+
+ for (i = 0; i < g_strv_length (fields); i++) {
+ TrackerFieldData *fd;
+
+ fd = tracker_metadata_add_metadata_field (iface, service_type, &field_list, fields[i], TRUE, FALSE);
+
+ if (!fd) {
+ g_string_free (sql_select, TRUE);
+ g_string_free (sql_from, TRUE);
+ g_string_free (sql_where, TRUE);
+ g_string_free (sql_order, TRUE);
+ g_string_free (sql_group, TRUE);
+
+ g_set_error (error, TRACKER_DBUS_ERROR, 0,
+ "Invalid or non-existant metadata type '%s' specified",
+ fields[i]);
+ return NULL;
+ }
+
+ if (i) {
+ g_string_append_printf (sql_select, ",");
+ g_string_append_printf (sql_order, ",");
+ g_string_append_printf (sql_group, ",");
+ }
+
+ g_string_append_printf (sql_select, "COALESCE(%s,'')", tracker_field_data_get_select_field (fd));
+ g_string_append_printf (sql_order, " %s %s",
+ tracker_field_data_get_select_field (fd),
order_desc ? "DESC" : "ASC" );
g_string_append_printf (sql_group, "COALESCE(%s,'')", tracker_field_data_get_select_field (fd));
}
+ if (concat_field && !(tracker_is_empty_string (concat_field))) {
+ TrackerFieldData *fd;
+ TrackerFieldType data_type;
+
+ fd = tracker_metadata_add_metadata_field (iface, service_type, &field_list, concat_field, TRUE, FALSE);
+
+ if (!fd) {
+ g_string_free (sql_select, TRUE);
+ g_string_free (sql_from, TRUE);
+ g_string_free (sql_where, TRUE);
+ g_string_free (sql_order, TRUE);
+ g_string_free (sql_group, TRUE);
+
+ g_set_error (error, TRACKER_DBUS_ERROR, 0,
+ "Invalid or non-existant metadata type '%s' specified",
+ sum_field);
+ return NULL;
+ }
+
+ data_type = tracker_field_data_get_data_type (fd);
+
+ if (!is_data_type_text (data_type)) {
+ g_string_free (sql_select, TRUE);
+ g_string_free (sql_from, TRUE);
+ g_string_free (sql_where, TRUE);
+ g_string_free (sql_order, TRUE);
+ g_string_free (sql_group, TRUE);
+
+ g_set_error (error, TRACKER_DBUS_ERROR, 0,
+ "Cannot sum '%s': this metadata type is not text",
+ sum_field);
+ return NULL;
+ }
+
+ g_string_append_printf (sql_select, ", GROUP_CONCAT (DISTINCT %s)", tracker_field_data_get_select_field (fd));
+ }
+
if (count_field && !(tracker_is_empty_string (count_field))) {
TrackerFieldData *fd;
Modified: trunk/src/libtracker-data/tracker-data-search.h
==============================================================================
--- trunk/src/libtracker-data/tracker-data-search.h (original)
+++ trunk/src/libtracker-data/tracker-data-search.h Wed Feb 25 17:38:56 2009
@@ -110,6 +110,17 @@
gint max_hits,
GError **error);
+TrackerDBResultSet *tracker_data_search_get_unique_values_with_concat_count_and_sum (const gchar *service_type,
+ gchar **fields,
+ const gchar *query_condition,
+ const gchar *concat_field,
+ const gchar *count,
+ const gchar *sum,
+ gboolean order_desc,
+ gint offset,
+ gint max_hits,
+ GError **error);
+
TrackerDBResultSet *tracker_data_search_metadata_in_path (const gchar *path,
gchar **fields,
GError **error);
Modified: trunk/src/libtracker-data/tracker-rdf-query.c
==============================================================================
--- trunk/src/libtracker-data/tracker-rdf-query.c (original)
+++ trunk/src/libtracker-data/tracker-rdf-query.c Wed Feb 25 17:38:56 2009
@@ -1191,7 +1191,7 @@
tracker_rdf_error_quark (),
PARSE_ERROR,
"RDF Query failed, field:'%s' not found",
- sort_fields[i]);
+ fields[i]);
g_slist_foreach (data.fields,
(GFunc) g_object_unref,
@@ -1315,6 +1315,7 @@
TrackerFieldData *field_data;
field_data = add_metadata_field (&data, sort_fields[i], FALSE, FALSE);
+ tracker_field_data_set_needs_join (field_data, TRUE);
if (!field_data) {
g_set_error (error,
Modified: trunk/src/libtracker/tracker.c
==============================================================================
--- trunk/src/libtracker/tracker.c (original)
+++ trunk/src/libtracker/tracker.c Wed Feb 25 17:38:56 2009
@@ -591,6 +591,18 @@
return table;
}
+GPtrArray *
+tracker_metadata_get_unique_values_with_concat_count_and_sum (TrackerClient *client, ServiceType service, char **meta_types, char *query, char *concat, char *count, char *sum, gboolean descending, int offset, int max_hits, GError **error)
+{
+ GPtrArray *table;
+ const char *service_str = tracker_service_types[service];
+
+ if (!org_freedesktop_Tracker_Metadata_get_unique_values_with_concat_count_and_sum (client->proxy_metadata, service_str, (const char **)meta_types, query, concat, count, sum, descending, offset, max_hits, &table, &*error)) {
+ return NULL;
+ }
+
+ return table;
+}
GPtrArray *
tracker_keywords_get_list (TrackerClient *client, ServiceType service, GError **error)
@@ -1243,6 +1255,20 @@
}
+void
+tracker_metadata_get_unique_values_with_concat_count_and_sum_async (TrackerClient *client, ServiceType service, char **meta_types, const char *query, char *concat, char *count, char *sum, gboolean descending, int offset, int max_hits, TrackerGPtrArrayReply callback, gpointer user_data)
+{
+
+ GPtrArrayCallBackStruct *callback_struct;
+ const char *service_str = tracker_service_types[service];
+
+ callback_struct = g_new (GPtrArrayCallBackStruct, 1);
+ callback_struct->callback = callback;
+ callback_struct->data = user_data;
+
+ client->last_pending_call = org_freedesktop_Tracker_Metadata_get_unique_values_with_concat_count_and_sum_async (client->proxy_metadata, service_str, (const char **) meta_types, query, concat, count, sum, descending, offset, max_hits, tracker_GPtrArray_reply, callback_struct);
+
+}
void
tracker_keywords_get_list_async (TrackerClient *client, ServiceType service, TrackerGPtrArrayReply callback, gpointer user_data)
Modified: trunk/src/libtracker/tracker.h
==============================================================================
--- trunk/src/libtracker/tracker.h (original)
+++ trunk/src/libtracker/tracker.h Wed Feb 25 17:38:56 2009
@@ -131,7 +131,7 @@
int tracker_metadata_get_count (TrackerClient *client, ServiceType service, char *field, char *query, GError **error);
GPtrArray * tracker_metadata_get_unique_values_with_count (TrackerClient *client, ServiceType service, char **meta_types, char *query, char *count, gboolean descending, int offset, int max_hits, GError **error);
GPtrArray * tracker_metadata_get_unique_values_with_count_and_sum (TrackerClient *client, ServiceType service, char **meta_types, char *query, char *count, char *sum, gboolean descending, int offset, int max_hits, GError **error);
-
+GPtrArray * tracker_metadata_get_unique_values_with_concat_count_and_sum (TrackerClient *client, ServiceType service, char **meta_types, char *query, char *concat, char *count, char *sum, gboolean descending, int offset, int max_hits, GError **error);
GPtrArray * tracker_keywords_get_list (TrackerClient *client, ServiceType service, GError **error);
char ** tracker_keywords_get (TrackerClient *client, ServiceType service, const char *id, GError **error);
@@ -195,6 +195,7 @@
void tracker_metadata_get_count_async (TrackerClient *client, ServiceType service, char *field, char *query, TrackerIntReply callback, gpointer user_data);
void tracker_metadata_get_unique_values_with_count_async (TrackerClient *client, ServiceType service, char **meta_types, const char *query, char *count, gboolean descending, int offset, int max_hits, TrackerGPtrArrayReply callback, gpointer user_data);
void tracker_metadata_get_unique_values_with_count_and_sum_async (TrackerClient *client, ServiceType service, char **meta_types, const char *query, char *count, char *sum, gboolean descending, int offset, int max_hits, TrackerGPtrArrayReply callback, gpointer user_data);
+void tracker_metadata_get_unique_values_with_concat_count_and_sum_async (TrackerClient *client, ServiceType service, char **meta_types, const char *query, char *concat, char *count, char *sum, gboolean descending, int offset, int max_hits, TrackerGPtrArrayReply callback, gpointer user_data);
void tracker_keywords_get_list_async (TrackerClient *client, ServiceType service, TrackerGPtrArrayReply callback, gpointer user_data);
void tracker_keywords_get_async (TrackerClient *client, ServiceType service, const char *id, TrackerArrayReply callback, gpointer user_data);
Modified: trunk/src/tracker-utils/tracker-unique.c
==============================================================================
--- trunk/src/tracker-utils/tracker-unique.c (original)
+++ trunk/src/tracker-utils/tracker-unique.c Wed Feb 25 17:38:56 2009
@@ -38,6 +38,7 @@
static gchar **fields;
static gchar *service;
static gchar *path;
+static gchar *concat;
static gchar *count;
static gchar *sum;
static gboolean descending;
@@ -51,6 +52,10 @@
N_("Search from a specific service"),
NULL
},
+ { "concat", 'n', 0, G_OPTION_ARG_STRING, &concat,
+ N_("Concatenate different values of this field"),
+ "e.g. File:Mime"
+ },
{ "count", 'c', 0, G_OPTION_ARG_STRING, &count,
N_("Count instances of unique fields of this type"),
"e.g. File:Mime"
@@ -192,16 +197,17 @@
}
}
- array = tracker_metadata_get_unique_values_with_count_and_sum (client,
- type,
- fields,
- buffer,
- count,
- sum,
- descending,
- 0,
- 512,
- &error);
+ array = tracker_metadata_get_unique_values_with_concat_count_and_sum (client,
+ type,
+ fields,
+ buffer,
+ concat,
+ count,
+ sum,
+ descending,
+ 0,
+ 512,
+ &error);
g_free (buffer);
if (error) {
Modified: trunk/src/trackerd/tracker-metadata.c
==============================================================================
--- trunk/src/trackerd/tracker-metadata.c (original)
+++ trunk/src/trackerd/tracker-metadata.c Wed Feb 25 17:38:56 2009
@@ -646,6 +646,75 @@
}
void
+tracker_metadata_get_unique_values_with_concat_count_and_sum (TrackerMetadata *object,
+ const gchar *service_type,
+ gchar **fields,
+ const gchar *query_condition,
+ const gchar *concat_field,
+ const gchar *count_field,
+ const gchar *sum_field,
+ gboolean order_desc,
+ gint offset,
+ gint max_hits,
+ DBusGMethodInvocation *context,
+ GError **error)
+{
+ TrackerDBResultSet *result_set = NULL;
+ guint request_id;
+ GPtrArray *values = NULL;
+ 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 (fields != NULL, context);
+ tracker_dbus_async_return_if_fail (query_condition != NULL, context);
+
+ tracker_dbus_request_new (request_id,
+ "DBus request to get unique values with count and sum, "
+ "service type:'%s', query '%s', "
+ "concat field :'%s' "
+ "count field :'%s', "
+ "sum field :'%s'",
+ service_type,
+ query_condition,
+ concat_field,
+ count_field,
+ sum_field);
+
+ result_set =
+ tracker_data_search_get_unique_values_with_concat_count_and_sum (service_type,
+ fields,
+ query_condition,
+ concat_field,
+ count_field,
+ sum_field,
+ order_desc,
+ offset,
+ max_hits,
+ &actual_error);
+
+ if (actual_error) {
+ tracker_dbus_request_failed (request_id, &actual_error, NULL);
+ dbus_g_method_return_error (context, actual_error);
+ g_error_free (actual_error);
+ return;
+ }
+
+ values = tracker_dbus_query_result_to_ptr_array (result_set);
+
+ dbus_g_method_return (context, values);
+
+ tracker_dbus_results_ptr_array_free (&values);
+
+ if (result_set) {
+ g_object_unref (result_set);
+ }
+
+ tracker_dbus_request_success (request_id);
+}
+
+void
tracker_metadata_get_sum (TrackerMetadata *object,
const gchar *service_type,
const gchar *field,
Modified: trunk/src/trackerd/tracker-metadata.h
==============================================================================
--- trunk/src/trackerd/tracker-metadata.h (original)
+++ trunk/src/trackerd/tracker-metadata.h Wed Feb 25 17:38:56 2009
@@ -126,6 +126,19 @@
DBusGMethodInvocation *context,
GError **error);
+void tracker_metadata_get_unique_values_with_concat_count_and_sum (TrackerMetadata *object,
+ const gchar *service_type,
+ gchar **fields,
+ const gchar *query_condition,
+ const gchar *concat,
+ const gchar *count,
+ const gchar *sum,
+ gboolean order_desc,
+ gint offset,
+ gint max_hits,
+ DBusGMethodInvocation *context,
+ GError **error);
+
G_END_DECLS
#endif /* __TRACKERD_METADATA_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]