[tracker/wip/carlosg/sparql1.1: 6/56] libtracker-data: Use single column for times/dates
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/sparql1.1: 6/56] libtracker-data: Use single column for times/dates
- Date: Thu, 6 Jun 2019 11:16:40 +0000 (UTC)
commit 9a875c6e5b18644038424da0e61a58af5ff7e03b
Author: Carlos Garnacho <carlosg gnome org>
Date: Sun Mar 3 21:44:18 2019 +0100
libtracker-data: Use single column for times/dates
Instead of having it split across 3 columns, use a single time column
that can either store int64 timestamps (if conversion is lossless) or
ISO8601 time strings.
src/libtracker-data/tracker-data-manager.c | 149 +++++++---------------
src/libtracker-data/tracker-data-update.c | 43 +++----
src/libtracker-data/tracker-db-interface-sqlite.c | 14 +-
src/libtracker-data/tracker-sparql.c | 72 +++--------
4 files changed, 86 insertions(+), 192 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index cce5e3610..a5ccb9196 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -218,6 +218,7 @@ set_index_for_single_value_property (TrackerDBInterface *iface,
const gchar *service_name,
const gchar *field_name,
gboolean enabled,
+ gboolean datetime,
GError **error)
{
GError *internal_error = NULL;
@@ -237,16 +238,24 @@ set_index_for_single_value_property (TrackerDBInterface *iface,
}
if (enabled) {
+ gchar *expr;
+
+ if (datetime)
+ expr = g_strdup_printf ("SparqlTimeSort(\"%s\")", field_name);
+ else
+ expr = g_strdup_printf ("\"%s\"", field_name);
+
g_debug ("Creating index (single-value property): "
- "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\")",
- service_name, field_name, service_name, field_name);
+ "CREATE INDEX \"%s_%s\" ON \"%s\" (%s)",
+ service_name, field_name, service_name, expr);
tracker_db_interface_execute_query (iface, &internal_error,
- "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\")",
+ "CREATE INDEX \"%s_%s\" ON \"%s\" (%s)",
service_name,
field_name,
service_name,
- field_name);
+ expr);
+ g_free (expr);
if (internal_error) {
g_propagate_error (error, internal_error);
@@ -260,9 +269,11 @@ set_index_for_multi_value_property (TrackerDBInterface *iface,
const gchar *field_name,
gboolean enabled,
gboolean recreate,
+ gboolean datetime,
GError **error)
{
GError *internal_error = NULL;
+ gchar *expr;
g_debug ("Dropping index (multi-value property): "
"DROP INDEX IF EXISTS \"%s_%s_ID_ID\"",
@@ -299,6 +310,11 @@ set_index_for_multi_value_property (TrackerDBInterface *iface,
return;
}
+ if (datetime)
+ expr = g_strdup_printf ("SparqlTimeSort(\"%s\")", field_name);
+ else
+ expr = g_strdup_printf ("\"%s\"", field_name);
+
if (enabled) {
g_debug ("Creating index (multi-value property): "
"CREATE INDEX \"%s_%s_ID\" ON \"%s_%s\" (ID)",
@@ -320,20 +336,20 @@ set_index_for_multi_value_property (TrackerDBInterface *iface,
}
g_debug ("Creating index (multi-value property): "
- "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (\"%s\", ID)",
+ "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (%s, ID)",
service_name,
field_name,
service_name,
field_name,
- field_name);
+ expr);
tracker_db_interface_execute_query (iface, &internal_error,
- "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\"
(\"%s\", ID)",
+ "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (%s,
ID)",
service_name,
field_name,
service_name,
field_name,
- field_name);
+ expr);
if (internal_error) {
g_propagate_error (error, internal_error);
@@ -341,25 +357,27 @@ set_index_for_multi_value_property (TrackerDBInterface *iface,
}
} else {
g_debug ("Creating index (multi-value property): "
- "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID, \"%s\")",
+ "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID, %s)",
service_name,
field_name,
service_name,
field_name,
- field_name);
+ expr);
tracker_db_interface_execute_query (iface, &internal_error,
- "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID,
\"%s\")",
+ "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID,
%s)",
service_name,
field_name,
service_name,
field_name,
- field_name);
+ expr);
if (internal_error) {
g_propagate_error (error, internal_error);
}
}
+
+ g_free (expr);
}
static gboolean
@@ -573,17 +591,20 @@ fix_indexed (TrackerDataManager *manager,
TrackerClass *class;
const gchar *service_name;
const gchar *field_name;
+ gboolean datetime;
iface = tracker_db_manager_get_writable_db_interface (manager->db_manager);
class = tracker_property_get_domain (property);
field_name = tracker_property_get_name (property);
service_name = tracker_class_get_name (class);
+ datetime = tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME;
if (tracker_property_get_multiple_values (property)) {
set_index_for_multi_value_property (iface, service_name, field_name,
tracker_property_get_indexed (property),
recreate,
+ datetime,
&internal_error);
} else {
TrackerProperty *secondary_index;
@@ -593,6 +614,7 @@ fix_indexed (TrackerDataManager *manager,
if (secondary_index == NULL) {
set_index_for_single_value_property (iface, service_name, field_name,
recreate && tracker_property_get_indexed
(property),
+ datetime,
&internal_error);
} else {
set_secondary_index_for_single_value_property (iface, service_name, field_name,
@@ -608,6 +630,7 @@ fix_indexed (TrackerDataManager *manager,
tracker_class_get_name (*domain_index_classes),
field_name,
recreate,
+ datetime,
&internal_error);
domain_index_classes++;
}
@@ -2531,15 +2554,6 @@ range_change_for (TrackerProperty *property,
g_string_append_printf (sel_col_sql, ", \"%s\", \"%s:graph\"",
field_name, field_name);
-
- g_string_append_printf (in_col_sql, ", \"%s:localDate\", \"%s:localTime\"",
- tracker_property_get_name (property),
- tracker_property_get_name (property));
-
- g_string_append_printf (sel_col_sql, ", \"%s:localDate\", \"%s:localTime\"",
- tracker_property_get_name (property),
- tracker_property_get_name (property));
-
} else if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_BOOLEAN) {
g_string_append_printf (sel_col_sql, ", \"%s\" != 0, \"%s:graph\"",
field_name, field_name);
@@ -2562,7 +2576,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
GError *internal_error = NULL;
const char *field_name;
const char *sql_type;
- gboolean not_single;
+ gboolean not_single, datetime;
field_name = tracker_property_get_name (property);
@@ -2587,6 +2601,8 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
break;
}
+ datetime = tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME;
+
if (!in_update || (in_update && (tracker_property_get_is_new (property) ||
tracker_property_get_is_new_domain_index (property, service) ||
tracker_property_get_cardinality_changed (property) ||
@@ -2652,16 +2668,6 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
range_change_for (property, in_col_sql, sel_col_sql, field_name);
}
- if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME) {
- /* xsd:dateTime is stored in three columns:
- * universal time, local date, local time of day */
- g_string_append_printf (sql,
- ", \"%s:localDate\" INTEGER NOT NULL"
- ", \"%s:localTime\" INTEGER NOT NULL",
- tracker_property_get_name (property),
- tracker_property_get_name (property));
- }
-
tracker_db_interface_execute_query (iface, &internal_error,
"%s)", sql->str);
@@ -2675,6 +2681,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
/* use different UNIQUE index for properties whose
* value should be indexed to minimize index size */
set_index_for_multi_value_property (iface, service_name, field_name, TRUE,
TRUE,
+ datetime,
&internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
@@ -2682,6 +2689,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
}
} else {
set_index_for_multi_value_property (iface, service_name, field_name, FALSE,
TRUE,
+ datetime,
&internal_error);
/* we still have to include the property value in
* the unique index for proper constraints */
@@ -2723,6 +2731,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
/* use different UNIQUE index for properties whose
* value should be indexed to minimize index size */
set_index_for_multi_value_property (iface, service_name, field_name, TRUE,
TRUE,
+ datetime,
&internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
@@ -2730,6 +2739,7 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
}
} else {
set_index_for_multi_value_property (iface, service_name, field_name, FALSE,
TRUE,
+ datetime,
&internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
@@ -3067,10 +3077,11 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
domain_indexes = tracker_class_get_domain_indexes (service);
for (i = 0; i < n_props; i++) {
- gboolean is_domain_index;
+ gboolean is_domain_index, datetime;
property = properties[i];
is_domain_index = is_a_domain_index (domain_indexes, property);
+ datetime = tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME;
if (tracker_property_get_domain (property) == service || is_domain_index) {
gboolean put_change;
@@ -3143,21 +3154,6 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
if (is_domain_index && tracker_property_get_is_new_domain_index
(property, service)) {
schedule_copy (copy_schedule, property, field_name, ":graph");
}
-
- if (tracker_property_get_data_type (property) ==
TRACKER_PROPERTY_TYPE_DATETIME) {
- /* xsd:dateTime is stored in three columns:
- * universal time, local date, local time of day */
- g_string_append_printf (create_sql, ", \"%s:localDate\"
INTEGER, \"%s:localTime\" INTEGER",
- tracker_property_get_name (property),
- tracker_property_get_name (property));
-
- if (is_domain_index &&
tracker_property_get_is_new_domain_index (property, service)) {
- schedule_copy (copy_schedule, property, field_name,
":localTime");
- schedule_copy (copy_schedule, property, field_name,
":localDate");
- }
-
- }
-
} else if ((!is_domain_index && tracker_property_get_is_new (property)) ||
(is_domain_index && tracker_property_get_is_new_domain_index
(property, service))) {
GString *alter_sql = NULL;
@@ -3205,6 +3201,7 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
/* This is implicit for all domain-specific-indices */
set_index_for_single_value_property (iface, service_name,
field_name, TRUE,
+ datetime,
&internal_error);
if (internal_error) {
g_string_free (alter_sql, TRUE);
@@ -3239,58 +3236,6 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
}
g_string_free (alter_sql, TRUE);
-
- if (tracker_property_get_data_type (property) ==
TRACKER_PROPERTY_TYPE_DATETIME) {
- alter_sql = g_string_new ("ALTER TABLE ");
- g_string_append_printf (alter_sql, "\"%s\" ADD COLUMN
\"%s:localDate\" INTEGER",
- service_name,
- field_name);
- g_debug ("Altering: '%s'", alter_sql->str);
- tracker_db_interface_execute_query (iface, &internal_error,
- "%s", alter_sql->str);
-
- if (internal_error) {
- g_string_free (alter_sql, TRUE);
- g_propagate_error (error, internal_error);
- goto error_out;
- } else if (is_domain_index) {
- copy_from_domain_to_domain_index (iface, property,
- field_name,
":localDate",
- service,
- &internal_error);
- if (internal_error) {
- g_string_free (alter_sql, TRUE);
- g_propagate_error (error, internal_error);
- goto error_out;
- }
- }
-
- g_string_free (alter_sql, TRUE);
-
- alter_sql = g_string_new ("ALTER TABLE ");
- g_string_append_printf (alter_sql, "\"%s\" ADD COLUMN
\"%s:localTime\" INTEGER",
- service_name,
- field_name);
- g_debug ("Altering: '%s'", alter_sql->str);
- tracker_db_interface_execute_query (iface, &internal_error,
- "%s", alter_sql->str);
- if (internal_error) {
- g_string_free (alter_sql, TRUE);
- g_propagate_error (error, internal_error);
- goto error_out;
- } else if (is_domain_index) {
- copy_from_domain_to_domain_index (iface, property,
- field_name,
":localTime",
- service,
- &internal_error);
- if (internal_error) {
- g_string_free (alter_sql, TRUE);
- g_propagate_error (error, internal_error);
- goto error_out;
- }
- }
- g_string_free (alter_sql, TRUE);
- }
} else {
put_change = TRUE;
}
@@ -3317,7 +3262,7 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
for (field_it = class_properties; field_it != NULL; field_it = field_it->next) {
TrackerProperty *field, *secondary_index;
const char *field_name;
- gboolean is_domain_index;
+ gboolean is_domain_index, datetime;
field = field_it->data;
@@ -3328,11 +3273,13 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
&& (tracker_property_get_indexed (field) || is_domain_index)) {
field_name = tracker_property_get_name (field);
+ datetime = tracker_property_get_data_type (field) == TRACKER_PROPERTY_TYPE_DATETIME;
secondary_index = tracker_property_get_secondary_index (field);
if (secondary_index == NULL) {
set_index_for_single_value_property (iface, service_name,
field_name, TRUE,
+ datetime,
&internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 60bdfe07b..1fcc29584 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -789,9 +789,21 @@ statement_bind_gvalue (TrackerDBStatement *stmt,
break;
default:
if (type == TRACKER_TYPE_DATE_TIME) {
- tracker_db_statement_bind_double (stmt, (*idx)++, tracker_date_time_get_time (value));
- tracker_db_statement_bind_int (stmt, (*idx)++, tracker_date_time_get_local_date
(value));
- tracker_db_statement_bind_int (stmt, (*idx)++, tracker_date_time_get_local_time
(value));
+ gdouble time = tracker_date_time_get_time (value);
+ int offset = tracker_date_time_get_offset (value);
+
+ /* If we have anything that prevents a unix timestamp to be
+ * lossless, we use the ISO8601 string.
+ */
+ if (offset != 0 || floor (time) != time) {
+ gchar *str;
+
+ str = tracker_date_to_string (time, offset);
+ tracker_db_statement_bind_text (stmt, (*idx)++, str);
+ g_free (str);
+ } else {
+ tracker_db_statement_bind_int (stmt, (*idx)++, round (time));
+ }
} else {
g_warning ("Unknown type for binding: %s\n", G_VALUE_TYPE_NAME (value));
}
@@ -845,14 +857,6 @@ tracker_data_resource_buffer_flush (TrackerData *data,
"DELETE FROM \"%s\"
WHERE ID = ? AND \"%s\" = ?",
table_name,
property->name);
- } else if (property->date_time) {
- stmt = tracker_db_interface_create_statement (iface,
TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error,
- "INSERT OR IGNORE INTO
\"%s\" (ID, \"%s\", \"%s:localDate\", \"%s:localTime\", \"%s:graph\") VALUES (?, ?, ?, ?, ?)",
- table_name,
- property->name,
- property->name,
- property->name,
- property->name);
} else {
stmt = tracker_db_interface_create_statement (iface,
TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE, &actual_error,
"INSERT OR IGNORE INTO
\"%s\" (ID, \"%s\", \"%s:graph\") VALUES (?, ?, ?)",
@@ -955,12 +959,6 @@ tracker_data_resource_buffer_flush (TrackerData *data,
g_string_append_printf (sql, ", \"%s\"", property->name);
g_string_append (values_sql, ", ?");
- if (property->date_time) {
- g_string_append_printf (sql, ", \"%s:localDate\"",
property->name);
- g_string_append_printf (sql, ", \"%s:localTime\"",
property->name);
- g_string_append (values_sql, ", ?, ?");
- }
-
g_string_append_printf (sql, ", \"%s:graph\"", property->name);
g_string_append (values_sql, ", ?");
} else {
@@ -968,12 +966,6 @@ tracker_data_resource_buffer_flush (TrackerData *data,
g_string_append (sql, ", ");
}
g_string_append_printf (sql, "\"%s\" = ?", property->name);
-
- if (property->date_time) {
- g_string_append_printf (sql, ", \"%s:localDate\" = ?",
property->name);
- g_string_append_printf (sql, ", \"%s:localTime\" = ?",
property->name);
- }
-
g_string_append_printf (sql, ", \"%s:graph\" = ?", property->name);
}
}
@@ -1019,11 +1011,6 @@ tracker_data_resource_buffer_flush (TrackerData *data,
if (table->delete_value) {
/* just set value to NULL for single value properties */
tracker_db_statement_bind_null (stmt, param++);
- if (property->date_time) {
- /* also set localDate and localTime to NULL */
- tracker_db_statement_bind_null (stmt, param++);
- tracker_db_statement_bind_null (stmt, param++);
- }
} else {
statement_bind_gvalue (stmt, ¶m, &property->value);
}
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c
b/src/libtracker-data/tracker-db-interface-sqlite.c
index 8baddb26a..d253df52d 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -492,16 +492,12 @@ function_sparql_time_sort (sqlite3_context *context,
if (sqlite3_value_type (argv[0]) == SQLITE_NULL) {
sqlite3_result_null (context);
return;
- } else if (sqlite3_value_numeric_type (argv[0]) == SQLITE_INTEGER) {
- gint64 value;
-
- value = sqlite3_value_int64 (argv[0]);
- sort_key = value * G_USEC_PER_SEC;
+ } else if (sqlite3_value_numeric_type (argv[0]) == SQLITE_INTEGER ||
+ sqlite3_value_numeric_type (argv[0]) == SQLITE_FLOAT) {
+ gdouble value;
- if (sort_key < value) {
- sqlite3_result_error (context, "Invalid integer argument value", -1);
- return;
- }
+ value = sqlite3_value_double (argv[0]);
+ sort_key = (gint64) (value * G_USEC_PER_SEC);
} else if (sqlite3_value_type (argv[0]) == SQLITE_TEXT) {
const gchar *value;
gdouble time;
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index e36d2341e..347960e53 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -514,25 +514,8 @@ static void
_append_variable_sql (TrackerSparql *sparql,
TrackerVariable *variable)
{
- TrackerBinding *binding;
-
- binding = TRACKER_BINDING (tracker_variable_get_sample_binding (variable));
-
- if (binding &&
- binding->data_type == TRACKER_PROPERTY_TYPE_DATETIME) {
- TrackerVariable *local_time;
- gchar *name;
-
- name = g_strdup_printf ("%s:local", variable->name);
- local_time = _ensure_variable (sparql, name);
- g_free (name);
-
- _append_string_printf (sparql, "%s ",
- tracker_variable_get_sql_expression (local_time));
- } else {
- _append_string_printf (sparql, "%s ",
- tracker_variable_get_sql_expression (variable));
- }
+ _append_string_printf (sparql, "%s ",
+ tracker_variable_get_sql_expression (variable));
}
static void
@@ -1200,31 +1183,6 @@ _add_quad (TrackerSparql *sparql,
*/
tracker_variable_binding_set_nullable (TRACKER_VARIABLE_BINDING (binding),
TRUE);
}
-
- if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME) {
- gchar *date_var, *sql_expression, *local_date, *local_time;
- TrackerBinding *local_time_binding;
-
- /* Merge localDate/localTime into $var:local */
- date_var = g_strdup_printf ("%s:local", variable->name);
- variable = _ensure_variable (sparql, date_var);
-
- local_date = tracker_binding_get_extra_sql_expression (binding, "localDate");
- local_time = tracker_binding_get_extra_sql_expression (binding, "localTime");
- sql_expression = g_strdup_printf ("((%s * 24 * 3600) + %s)",
- local_date, local_time);
-
- local_time_binding = tracker_variable_binding_new (variable, NULL, NULL);
- tracker_binding_set_sql_expression (local_time_binding,
- sql_expression);
- _add_binding (sparql, local_time_binding);
- g_object_unref (local_time_binding);
-
- g_free (sql_expression);
- g_free (local_date);
- g_free (local_time);
- g_free (date_var);
- }
}
_add_binding (sparql, binding);
@@ -1386,8 +1344,8 @@ convert_expression_to_string (TrackerSparql *sparql,
break;
case TRACKER_PROPERTY_TYPE_DATE:
/* ISO 8601 format */
- _prepend_string (sparql, "strftime (\"%Y-%m-%d\", ");
- _append_string (sparql, ", \"unixepoch\") ");
+ _prepend_string (sparql, "strftime (\"%Y-%m-%d\", SparqlTimestamp (");
+ _append_string (sparql, "), \"unixepoch\") ");
break;
case TRACKER_PROPERTY_TYPE_DATETIME:
/* ISO 8601 format */
@@ -1562,8 +1520,14 @@ _end_triples_block (TrackerSparql *sparql,
first = FALSE;
binding = g_ptr_array_index (triple_context->literal_bindings, i);
- _append_string_printf (sparql, "%s = ", tracker_binding_get_sql_expression (binding));
- _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
+ if (binding->data_type == TRACKER_PROPERTY_TYPE_DATETIME) {
+ _append_string_printf (sparql, "SparqlTimeSort (%s) = SparqlTimeSort (",
tracker_binding_get_sql_expression (binding));
+ _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
+ _append_string (sparql, ") ");
+ } else {
+ _append_string_printf (sparql, "%s = ", tracker_binding_get_sql_expression (binding));
+ _append_literal_sql (sparql, TRACKER_LITERAL_BINDING (binding));
+ }
}
/* If we had any where clauses, prepend the 'WHERE' literal */
@@ -5380,12 +5344,12 @@ helper_translate_date (TrackerSparql *sparql,
GError **error)
{
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
- _append_string_printf (sparql, "strftime (\"%s\", ", format);
+ _append_string_printf (sparql, "strftime (\"%s\", SparqlTimestamp (", format);
_call_rule (sparql, NAMED_RULE_Expression, error);
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
- _append_string (sparql, ", \"unixepoch\") ");
+ _append_string (sparql, "), \"unixepoch\") ");
return TRUE;
}
@@ -5395,20 +5359,20 @@ helper_translate_time (TrackerSparql *sparql,
guint format,
GError **error)
{
+ _append_string (sparql, "CAST (SparqlTimestamp (");
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_OPEN_PARENS);
_call_rule (sparql, NAMED_RULE_Expression, error);
-
_expect (sparql, RULE_TYPE_LITERAL, LITERAL_CLOSE_PARENS);
switch (format) {
case TIME_FORMAT_SECONDS:
- _append_string (sparql, " % 60 ");
+ _append_string (sparql, ") AS INTEGER) % 60 ");
break;
case TIME_FORMAT_MINUTES:
- _append_string (sparql, " / 60 % 60 ");
+ _append_string (sparql, ") AS INTEGER) / 60 % 60 ");
break;
case TIME_FORMAT_HOURS:
- _append_string (sparql, " / 3600 % 24 ");
+ _append_string (sparql, ") AS INTEGER) / 3600 % 24 ");
break;
default:
g_assert_not_reached ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]