[tracker] libtracker-data, -common: Error reporting for timezone handling



commit 140550cd08a7f27f684c6ce4f5e7e0ab58f42807
Author: Philip Van Hoof <philip codeminded be>
Date:   Mon Feb 22 17:40:10 2010 +0100

    libtracker-data, -common: Error reporting for timezone handling

 src/libtracker-common/libtracker-common.vapi      |    8 ++++-
 src/libtracker-common/tracker-date-time.c         |   40 ++++++++++++++++-----
 src/libtracker-common/tracker-date-time.h         |   19 ++++++++--
 src/libtracker-data/tracker-data-manager.c        |    4 +-
 src/libtracker-data/tracker-data-update.c         |   33 ++++++++++++-----
 src/libtracker-data/tracker-sparql-query.vala     |   24 ++++++------
 src/plugins/evolution/tracker-evolution-plugin.c  |   13 ++++++-
 tests/libtracker-common/tracker-type-utils-test.c |   16 ++++++--
 8 files changed, 115 insertions(+), 42 deletions(-)
---
diff --git a/src/libtracker-common/libtracker-common.vapi b/src/libtracker-common/libtracker-common.vapi
index e175151..e437d95 100644
--- a/src/libtracker-common/libtracker-common.vapi
+++ b/src/libtracker-common/libtracker-common.vapi
@@ -65,6 +65,12 @@ namespace Tracker {
 	}
 
 	[CCode (cheader_filename = "libtracker-common/tracker-date-time.h")]
-	public int string_to_date (string date_string, out int offset);
+	public int string_to_date (string date_string, out int offset) throws DateError;
+
+	[CCode (cheader_filename = "libtracker-common/tracker-date-time.h")]
+	public errordomain DateError {
+		OFFSET,
+		INVALID_ISO8601
+	}
 }
 
diff --git a/src/libtracker-common/tracker-date-time.c b/src/libtracker-common/tracker-date-time.c
index 4e159f0..1074208 100644
--- a/src/libtracker-common/tracker-date-time.c
+++ b/src/libtracker-common/tracker-date-time.c
@@ -34,6 +34,10 @@
 
 #define DATE_FORMAT_ISO8601 "%Y-%m-%dT%H:%M:%S%z"
 
+GQuark tracker_date_error_quark (void) {
+	return g_quark_from_static_string ("tracker_date_error-quark");
+}
+
 static const char *months[] = {
 	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
 	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
@@ -360,19 +364,25 @@ tracker_date_format_to_iso8601 (const gchar *date_string,
 }
 
 gchar *
-tracker_date_to_time_string (const gchar *date_string)
+tracker_date_to_time_string (const gchar *date_string, GError **error)
 {
 	gchar *str;
+	GError *new_error = NULL;
 
 	str = tracker_date_format (date_string);
 
 	if (str) {
 		time_t t;
 
-		t = tracker_string_to_date (str, NULL);
+		t = tracker_string_to_date (str, NULL, &new_error);
 
 		g_free (str);
 
+		if (new_error) {
+			g_propagate_error (error, new_error);
+			return NULL;
+		}
+
 		if (t != -1) {
 			return tracker_gint_to_string (t);
 		}
@@ -383,7 +393,8 @@ tracker_date_to_time_string (const gchar *date_string)
 
 time_t
 tracker_string_to_date (const gchar *date_string,
-                        gint        *offset_p)
+                        gint        *offset_p,
+                        GError      **error)
 {
 	/* TODO Add more checks and use GError to report invalid input
 	 * as this is potential user input.
@@ -413,6 +424,8 @@ tracker_string_to_date (const gchar *date_string,
 
 	if (!g_regex_match (regex, date_string, 0, &match_info)) {
 		g_match_info_free (match_info);
+		g_set_error (error, TRACKER_DATE_ERROR, TRACKER_DATE_ERROR_INVALID_ISO8601,
+		             "Not a ISO 8601 date string");
 		return -1;
 	}
 
@@ -472,7 +485,8 @@ tracker_string_to_date (const gchar *date_string,
 			g_free (match);
 
 			if (offset < -14 * 3600 || offset > 14 * 3600) {
-				g_warning ("UTC offset too large: %d seconds", offset);
+				g_set_error (error, TRACKER_DATE_ERROR, TRACKER_DATE_ERROR_OFFSET,
+				             "UTC offset too large: %d seconds", offset);
 			}
 
 			t -= offset;
@@ -563,9 +577,9 @@ tracker_date_time_get_type (void)
 }
 
 void
-tracker_date_time_set (GValue *value,
-                       gint64  time,
-                       gint    offset)
+tracker_date_time_set (GValue  *value,
+                       gint64   time,
+                       gint     offset)
 {
 	g_return_if_fail (G_VALUE_HOLDS (value, TRACKER_TYPE_DATE_TIME));
 	g_return_if_fail (offset >= -14 * 3600 && offset <= 14 * 3600);
@@ -576,15 +590,23 @@ tracker_date_time_set (GValue *value,
 
 void
 tracker_date_time_set_from_string (GValue      *value,
-                                   const gchar *date_time_string)
+                                   const gchar *date_time_string,
+                                   GError     **error)
 {
 	gint64 time;
 	gint offset;
+	GError *new_error = NULL;
 
 	g_return_if_fail (G_VALUE_HOLDS (value, TRACKER_TYPE_DATE_TIME));
 	g_return_if_fail (date_time_string != NULL);
 
-	time = tracker_string_to_date (date_time_string, &offset);
+	time = tracker_string_to_date (date_time_string, &offset, &new_error);
+
+	if (new_error != NULL) {
+		g_propagate_error (error, new_error);
+		return;
+	}
+
 	tracker_date_time_set (value, time, offset);
 }
 
diff --git a/src/libtracker-common/tracker-date-time.h b/src/libtracker-common/tracker-date-time.h
index f3d6022..7f39401 100644
--- a/src/libtracker-common/tracker-date-time.h
+++ b/src/libtracker-common/tracker-date-time.h
@@ -30,7 +30,15 @@ G_BEGIN_DECLS
 #error "only <libtracker-common/tracker-common.h> must be included directly."
 #endif
 
+typedef enum  {
+	TRACKER_DATE_ERROR_OFFSET,
+	TRACKER_DATE_ERROR_INVALID_ISO8601
+} TrackerDateError;
+
 #define TRACKER_TYPE_DATE_TIME                 (tracker_date_time_get_type ())
+#define TRACKER_DATE_ERROR                     tracker_date_error_quark ()
+
+GQuark   tracker_date_error_quark              (void);
 
 GType    tracker_date_time_get_type            (void);
 
@@ -38,7 +46,8 @@ void     tracker_date_time_set                 (GValue       *value,
                                                 gint64        time,
                                                 gint          offset);
 void     tracker_date_time_set_from_string     (GValue       *value,
-                                                const gchar  *date_time_string);
+                                                const gchar  *date_time_string,
+                                                GError      **error);
 gint64   tracker_date_time_get_time            (const GValue *value);
 gint     tracker_date_time_get_offset          (const GValue *value);
 gint     tracker_date_time_get_local_date      (const GValue *value);
@@ -47,10 +56,12 @@ gint     tracker_date_time_get_local_time      (const GValue *value);
 gchar *  tracker_date_format                   (const gchar  *date_string);
 gchar *  tracker_date_format_to_iso8601        (const gchar  *date_string,
                                                 const gchar  *format);
-gchar *  tracker_date_to_time_string           (const gchar  *date_string);
+gchar *  tracker_date_to_time_string           (const gchar  *date_string,
+                                                GError      **error);
 time_t   tracker_string_to_date                (const gchar  *date_string,
-                                                gint         *offset);
-gchar *  tracker_date_to_string                        (time_t        date_time);
+                                                gint         *offset,
+                                                GError      **error);
+gchar *  tracker_date_to_string                (time_t        date_time);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 7ebb972..86fe7fa 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -350,7 +350,7 @@ load_ontology_statement (const gchar *ontology_file,
 			return;
 		}
 
-		tracker_ontology_set_last_modified (ontology, tracker_string_to_date (object, NULL));
+		tracker_ontology_set_last_modified (ontology, tracker_string_to_date (object, NULL, NULL));
 	}
 
 }
@@ -444,7 +444,7 @@ get_ontology_from_file (const gchar *ontology_file)
 				return NULL;
 			}
 
-			tracker_ontology_set_last_modified (ontology, tracker_string_to_date (object, NULL));
+			tracker_ontology_set_last_modified (ontology, tracker_string_to_date (object, NULL, NULL));
 
 			/* This one is here because lower ontology_uris is destroyed, and
 			 * else would this one's reference also be destroyed with it */
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 6fd844c..a574ad6 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -1059,7 +1059,8 @@ get_old_property_values (TrackerProperty  *property,
 static void
 string_to_gvalue (const gchar         *value,
                   TrackerPropertyType  type,
-                  GValue              *gvalue)
+                  GValue              *gvalue,
+                  GError             **error)
 {
 	gint object_id;
 
@@ -1085,7 +1086,7 @@ string_to_gvalue (const gchar         *value,
 	case TRACKER_PROPERTY_TYPE_DATE:
 	case TRACKER_PROPERTY_TYPE_DATETIME:
 		g_value_init (gvalue, TRACKER_TYPE_DATE_TIME);
-		tracker_date_time_set_from_string (gvalue, value);
+		tracker_date_time_set_from_string (gvalue, value, error);
 		break;
 	case TRACKER_PROPERTY_TYPE_RESOURCE:
 		object_id = ensure_resource_id (value, NULL);
@@ -1108,14 +1109,16 @@ cache_set_metadata_decomposed (TrackerProperty  *property,
 	gchar              *table_name;
 	const gchar        *field_name;
 	TrackerProperty   **super_properties;
-	GValue gvalue = { 0 };
+	GValue              gvalue = { 0 };
 	GValueArray        *old_values;
+	GError             *new_error = NULL;
 
 	/* also insert super property values */
 	super_properties = tracker_property_get_super_properties (property);
 	while (*super_properties) {
-		cache_set_metadata_decomposed (*super_properties, value, graph, error);
-		if (*error) {
+		cache_set_metadata_decomposed (*super_properties, value, graph, &new_error);
+		if (new_error) {
+			g_propagate_error (error, new_error);
 			return;
 		}
 		super_properties++;
@@ -1134,13 +1137,19 @@ cache_set_metadata_decomposed (TrackerProperty  *property,
 	fts = tracker_property_get_fulltext_indexed (property);
 
 	/* read existing property values */
-	old_values = get_old_property_values (property, error);
-	if (*error) {
+	old_values = get_old_property_values (property, &new_error);
+	if (new_error) {
 		g_free (table_name);
+		g_propagate_error (error, new_error);
 		return;
 	}
 
-	string_to_gvalue (value, tracker_property_get_data_type (property), &gvalue);
+	string_to_gvalue (value, tracker_property_get_data_type (property), &gvalue, &new_error);
+	if (new_error) {
+		g_free (table_name);
+		g_propagate_error (error, new_error);
+		return;
+	}
 
 	if (!value_set_add_value (old_values, &gvalue)) {
 		/* value already inserted */
@@ -1195,7 +1204,13 @@ delete_metadata_decomposed (TrackerProperty  *property,
 		return;
 	}
 
-	string_to_gvalue (value, tracker_property_get_data_type (property), &gvalue);
+	string_to_gvalue (value, tracker_property_get_data_type (property), &gvalue, &new_error);
+
+	if (new_error) {
+		g_free (table_name);
+		g_propagate_error (error, new_error);
+		return;
+	}
 
 	if (!value_set_remove_value (old_values, &gvalue)) {
 		/* value not found */
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index f945fda..a53e5ec 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -511,7 +511,7 @@ public class Tracker.SparqlQuery : Object {
 		}
 	}
 
-	public PtrArray? execute_update (bool blank) throws DataError, DBInterfaceError, SparqlError {
+	public PtrArray? execute_update (bool blank) throws DataError, DBInterfaceError, SparqlError, DateError {
 		assert (update_extensions);
 
 		scanner = new SparqlScanner ((char*) query_string, (long) query_string.size ());
@@ -560,7 +560,7 @@ public class Tracker.SparqlQuery : Object {
 		return blank_nodes;
 	}
 
-	DBResultSet? exec_sql (string sql) throws DBInterfaceError, SparqlError {
+	DBResultSet? exec_sql (string sql) throws DBInterfaceError, SparqlError, DateError {
 		var iface = DBManager.get_db_interface ();
 		var stmt = iface.create_statement ("%s", sql);
 
@@ -722,7 +722,7 @@ public class Tracker.SparqlQuery : Object {
 		used_sql_identifiers = new HashTable<string,bool>.full (str_hash, str_equal, g_free, null);
 	}
 
-	DBResultSet? execute_select () throws DBInterfaceError, SparqlError {
+	DBResultSet? execute_select () throws DBInterfaceError, SparqlError, DateError {
 		// SELECT query
 
 		begin_query ();
@@ -920,7 +920,7 @@ public class Tracker.SparqlQuery : Object {
 		}
 	}
 
-	DBResultSet? execute_ask () throws DBInterfaceError, SparqlError {
+	DBResultSet? execute_ask () throws DBInterfaceError, SparqlError, DateError {
 		// ASK query
 
 		var pattern_sql = new StringBuilder ();
@@ -959,7 +959,7 @@ public class Tracker.SparqlQuery : Object {
 		}
 	}
 
-	PtrArray? execute_insert (bool blank) throws DBInterfaceError, DataError, SparqlError {
+	PtrArray? execute_insert (bool blank) throws DBInterfaceError, DataError, SparqlError, DateError {
 		expect (SparqlTokenType.INSERT);
 		if (accept (SparqlTokenType.INTO)) {
 			parse_from_or_into_param ();
@@ -969,7 +969,7 @@ public class Tracker.SparqlQuery : Object {
 		return execute_insert_or_delete (false, blank);
 	}
 
-	void execute_delete () throws DBInterfaceError, DataError, SparqlError {
+	void execute_delete () throws DBInterfaceError, DataError, SparqlError, DateError {
 		expect (SparqlTokenType.DELETE);
 		if (accept (SparqlTokenType.FROM)) {
 			parse_from_or_into_param ();
@@ -979,7 +979,7 @@ public class Tracker.SparqlQuery : Object {
 		execute_insert_or_delete (true, false);
 	}
 
-	PtrArray? execute_insert_or_delete (bool delete_statements, bool blank) throws DBInterfaceError, DataError, SparqlError {
+	PtrArray? execute_insert_or_delete (bool delete_statements, bool blank) throws DBInterfaceError, DataError, SparqlError, DateError {
 		// INSERT or DELETE
 
 		var pattern_sql = new StringBuilder ();
@@ -2132,7 +2132,7 @@ public class Tracker.SparqlQuery : Object {
 		}
 	}
 
-	void parse_construct_triples_block (HashTable<string,string> var_value_map) throws SparqlError, DataError {
+	void parse_construct_triples_block (HashTable<string,string> var_value_map) throws SparqlError, DataError, DateError {
 		expect (SparqlTokenType.OPEN_BRACE);
 
 		while (current () != SparqlTokenType.CLOSE_BRACE) {
@@ -2168,7 +2168,7 @@ public class Tracker.SparqlQuery : Object {
 	}
 
 
-	string parse_construct_var_or_term (HashTable<string,string> var_value_map) throws SparqlError, DataError {
+	string parse_construct_var_or_term (HashTable<string,string> var_value_map) throws SparqlError, DataError, DateError {
 		string result = "";
 		if (current () == SparqlTokenType.VAR) {
 			next ();
@@ -2246,7 +2246,7 @@ public class Tracker.SparqlQuery : Object {
 		return result;
 	}
 
-	void parse_construct_property_list_not_empty (HashTable<string,string> var_value_map) throws SparqlError, DataError {
+	void parse_construct_property_list_not_empty (HashTable<string,string> var_value_map) throws SparqlError, DataError, DateError {
 		while (true) {
 			var old_predicate = current_predicate;
 
@@ -2283,7 +2283,7 @@ public class Tracker.SparqlQuery : Object {
 		}
 	}
 
-	void parse_construct_object_list (HashTable<string,string> var_value_map) throws SparqlError, DataError {
+	void parse_construct_object_list (HashTable<string,string> var_value_map) throws SparqlError, DataError, DateError {
 		while (true) {
 			parse_construct_object (var_value_map);
 			if (accept (SparqlTokenType.COMMA)) {
@@ -2293,7 +2293,7 @@ public class Tracker.SparqlQuery : Object {
 		}
 	}
 
-	void parse_construct_object (HashTable<string,string> var_value_map) throws SparqlError, DataError {
+	void parse_construct_object (HashTable<string,string> var_value_map) throws SparqlError, DataError, DateError {
 		string object = parse_construct_var_or_term (var_value_map);
 		if (delete_statements) {
 			// delete triple from database
diff --git a/src/plugins/evolution/tracker-evolution-plugin.c b/src/plugins/evolution/tracker-evolution-plugin.c
index 842299f..a0e56ec 100644
--- a/src/plugins/evolution/tracker-evolution-plugin.c
+++ b/src/plugins/evolution/tracker-evolution-plugin.c
@@ -1725,7 +1725,18 @@ on_register_client_qry (GPtrArray *results,
 			} else {
 				for (i = 0; i < results->len; i++) {
 					const gchar **str = g_ptr_array_index (results, i);
-					info->last_checkout = (guint64) tracker_string_to_date (str[0], NULL);
+					GError *new_error = NULL;
+
+					info->last_checkout = (guint64) tracker_string_to_date (str[0], NULL, &new_error);
+
+					if (new_error) {
+						g_warning ("%s", new_error->message);
+						g_error_free (error);
+						g_ptr_array_foreach (results, (GFunc) g_strfreev, NULL);
+						g_ptr_array_free (results, TRUE);
+						return;
+					}
+
 					break;
 				}
 			}
diff --git a/tests/libtracker-common/tracker-type-utils-test.c b/tests/libtracker-common/tracker-type-utils-test.c
index 10fc7ba..ba1cfc7 100644
--- a/tests/libtracker-common/tracker-type-utils-test.c
+++ b/tests/libtracker-common/tracker-type-utils-test.c
@@ -75,6 +75,7 @@ test_string_to_date (void)
 	time_t     result_time_t;
 	const gchar  *input = "2008-06-16T11:10:10+0600";
 	gchar  *timezone = g_strdup (g_getenv ("TZ"));
+	GError *error = NULL;
 
 	if (! g_setenv ("TZ", "UTC", TRUE)) {
 		g_test_message ("unable to set timezone, test results are invalid, skipping\n");
@@ -86,7 +87,8 @@ test_string_to_date (void)
 
 	expected = g_date_new_dmy (16, G_DATE_JUNE, 2008);
 
-	result_time_t = tracker_string_to_date (input, NULL);
+	result_time_t = tracker_string_to_date (input, NULL, &error);
+	g_assert_no_error (error);
 
 	result = g_date_new ();
 	g_date_set_time_t (result, result_time_t);
@@ -101,15 +103,21 @@ test_string_to_date (void)
 	g_assert_cmpint (g_date_get_month (expected), ==, g_date_get_month (result));
 
 	if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR)) {
-		result_time_t = tracker_string_to_date (NULL, NULL);
+		result_time_t = tracker_string_to_date (NULL, NULL, NULL);
 	}
 	g_test_trap_assert_failed ();
 
-	result_time_t = tracker_string_to_date ("", NULL);
+	result_time_t = tracker_string_to_date ("", NULL, &error);
 	g_assert_cmpint (result_time_t, ==, -1);
+	g_assert_error (error, TRACKER_DATE_ERROR, TRACKER_DATE_ERROR_INVALID_ISO8601);
+	g_error_free (error);
+	error = NULL;
 
-	result_time_t = tracker_string_to_date ("i am not a date", NULL);
+	result_time_t = tracker_string_to_date ("i am not a date", NULL, &error);
 	g_assert_cmpint (result_time_t, ==, -1);
+	g_assert_error (error, TRACKER_DATE_ERROR, TRACKER_DATE_ERROR_INVALID_ISO8601);
+	g_error_free (error);
+	error = NULL;
 
 	/* Fails! Check the code
 	   result_time_t = tracker_string_to_date ("2008-06-32T04:23:10+0000", NULL);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]