diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2022-05-22 14:15:36 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2022-08-30 17:16:48 +0200 |
commit | d34f5e2ca482640784a1bc523ce2ec6766b73af0 (patch) | |
tree | f931254b1df8c22f06878c578ea40df0b68dea93 /src | |
parent | d6e4b9307950d1c74da462ba4e4c1e0fb43c21f0 (diff) | |
download | tracker-d34f5e2ca482640784a1bc523ce2ec6766b73af0.tar.gz |
libtracker-sparql: Add function to get GValue array from a TrackerDBStatement
All of our SELECT queries performed from the update machinery return a single
column. Add a simple function that can handle returning an array of GValues
for those cases, so we avoid the TrackerDBCursor GObject creation hot paths.
Diffstat (limited to 'src')
-rw-r--r-- | src/libtracker-sparql/core/tracker-db-interface-sqlite.c | 113 | ||||
-rw-r--r-- | src/libtracker-sparql/core/tracker-db-interface-sqlite.h | 4 |
2 files changed, 117 insertions, 0 deletions
diff --git a/src/libtracker-sparql/core/tracker-db-interface-sqlite.c b/src/libtracker-sparql/core/tracker-db-interface-sqlite.c index 56dc573c6..1cc1269e2 100644 --- a/src/libtracker-sparql/core/tracker-db-interface-sqlite.c +++ b/src/libtracker-sparql/core/tracker-db-interface-sqlite.c @@ -3724,6 +3724,119 @@ tracker_db_statement_execute (TrackerDBStatement *stmt, tracker_db_statement_sqlite_release (stmt); } +GArray * +tracker_db_statement_get_values (TrackerDBStatement *stmt, + TrackerPropertyType type, + GError **error) +{ + gint result = SQLITE_OK; + GArray *values; + + tracker_db_interface_lock (stmt->db_interface); + tracker_db_interface_ref_use (stmt->db_interface); + tracker_db_statement_sqlite_grab (stmt); + +#ifdef G_ENABLE_DEBUG + if (TRACKER_DEBUG_CHECK (SQL_STATEMENTS)) { + gchar *full_query; + + full_query = sqlite3_expanded_sql (stmt->stmt); + + if (full_query) { + g_message ("Executing query: '%s'", full_query); + sqlite3_free (full_query); + } else { + g_message ("Executing query: '%s'", + sqlite3_sql (stmt->stmt)); + } + } +#endif + + values = g_array_new (FALSE, TRUE, sizeof (GValue)); + g_array_set_clear_func (values, (GDestroyNotify) g_value_unset); + + while (TRUE) { + GError *inner_error = NULL; + GDateTime *datetime; + GValue gvalue = G_VALUE_INIT; + + result = stmt_step (stmt->stmt); + + if (result == SQLITE_DONE) { + break; + } else if (result != SQLITE_ROW) { + g_set_error (error, + TRACKER_DB_INTERFACE_ERROR, + TRACKER_DB_QUERY_ERROR, + "%s", sqlite3_errmsg (stmt->db_interface->db)); + g_clear_pointer (&values, g_array_unref); + break; + } + + if (sqlite3_column_type (stmt->stmt, 0) == SQLITE_NULL) + continue; + + switch (type) { + case TRACKER_PROPERTY_TYPE_UNKNOWN: + case TRACKER_PROPERTY_TYPE_STRING: + g_value_init (&gvalue, G_TYPE_STRING); + g_value_set_string (&gvalue, (gchar *) sqlite3_column_text (stmt->stmt, 0)); + break; + case TRACKER_PROPERTY_TYPE_LANGSTRING: { + sqlite3_value *val = sqlite3_column_value (stmt->stmt, 0); + gchar *text; + + text = g_strdup ((const gchar *) sqlite3_value_text (val)); + + g_value_init (&gvalue, G_TYPE_BYTES); + g_value_take_boxed (&gvalue, + g_bytes_new_with_free_func (text, + sqlite3_value_bytes (val), + g_free, text)); + break; + } + case TRACKER_PROPERTY_TYPE_DOUBLE: + g_value_init (&gvalue, G_TYPE_DOUBLE); + g_value_set_double (&gvalue, sqlite3_column_double (stmt->stmt, 0)); + break; + case TRACKER_PROPERTY_TYPE_BOOLEAN: + case TRACKER_PROPERTY_TYPE_INTEGER: + case TRACKER_PROPERTY_TYPE_RESOURCE: + g_value_init (&gvalue, G_TYPE_INT64); + g_value_set_int64 (&gvalue, sqlite3_column_int64 (stmt->stmt, 0)); + break; + case TRACKER_PROPERTY_TYPE_DATE: + case TRACKER_PROPERTY_TYPE_DATETIME: + if (sqlite3_column_type (stmt->stmt, 0) == SQLITE_INTEGER) { + datetime = g_date_time_new_from_unix_utc (sqlite3_column_int64 (stmt->stmt, 0)); + } else { + datetime = tracker_date_new_from_iso8601 ((const gchar *) sqlite3_column_text (stmt->stmt, 0), + &inner_error); + if (!datetime) + break; + } + + g_value_init (&gvalue, G_TYPE_DATE_TIME); + g_value_take_boxed (&gvalue, datetime); + break; + } + + if (inner_error) { + g_propagate_error (error, inner_error); + g_clear_pointer (&values, g_array_unref); + break; + } + + g_array_append_val (values, gvalue); + } + + tracker_db_statement_sqlite_release (stmt); + tracker_db_interface_unref_use (stmt->db_interface); + tracker_db_interface_unlock (stmt->db_interface); + + return values; +} + TrackerDBCursor * tracker_db_statement_start_cursor (TrackerDBStatement *stmt, GError **error) diff --git a/src/libtracker-sparql/core/tracker-db-interface-sqlite.h b/src/libtracker-sparql/core/tracker-db-interface-sqlite.h index fedd27df3..265919045 100644 --- a/src/libtracker-sparql/core/tracker-db-interface-sqlite.h +++ b/src/libtracker-sparql/core/tracker-db-interface-sqlite.h @@ -94,6 +94,10 @@ gssize tracker_db_interface_sqlite_release_memory (TrackerD void tracker_db_interface_ref_use (TrackerDBInterface *db_interface); gboolean tracker_db_interface_unref_use (TrackerDBInterface *db_interface); +GArray * tracker_db_statement_get_values (TrackerDBStatement *stmt, + TrackerPropertyType type, + GError **error); + G_END_DECLS #endif /* __LIBTRACKER_DB_INTERFACE_SQLITE_H__ */ |