Use prepared query when getting getting the bkc tags

There's no point parsing and optimizing this query 12 times at startup.
This commit is contained in:
Richard Hughes 2022-12-12 12:43:23 +00:00
parent 707b1ed6d5
commit 0d0ffa4708

View File

@ -109,6 +109,7 @@ struct _FuEngine {
XbQuery *query_component_by_guid; XbQuery *query_component_by_guid;
XbQuery *query_container_checksum1; XbQuery *query_container_checksum1;
XbQuery *query_container_checksum2; XbQuery *query_container_checksum2;
XbQuery *query_tag_by_guid_version;
guint coldplug_id; guint coldplug_id;
FuPluginList *plugin_list; FuPluginList *plugin_list;
GPtrArray *plugin_filter; GPtrArray *plugin_filter;
@ -493,26 +494,14 @@ fu_engine_add_local_release_metadata(FuEngine *self, FuRelease *release, GError
{ {
FuDevice *dev = fu_release_get_device(release); FuDevice *dev = fu_release_get_device(release);
GPtrArray *guids; GPtrArray *guids;
g_autoptr(XbQuery) query = NULL;
g_autoptr(GError) error_query = NULL;
/* no device matched */ /* no device matched */
if (dev == NULL) if (dev == NULL)
return TRUE; return TRUE;
/* prepare query with bound GUID parameter */ /* not set up */
query = xb_query_new_full(self->silo, if (self->query_tag_by_guid_version == NULL)
"local/components/component[@merge='append']/provides/" return TRUE;
"firmware[text()=?]/../../releases/release[@version=?]/../../"
"tags/tag",
XB_QUERY_FLAG_OPTIMIZE | XB_QUERY_FLAG_USE_INDEXES,
&error_query);
if (query == NULL) {
if (g_error_matches(error_query, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT))
return TRUE;
g_propagate_error(error, g_steal_pointer(&error_query));
return FALSE;
}
/* use prepared query for each GUID */ /* use prepared query for each GUID */
guids = fu_device_get_guids(dev); guids = fu_device_get_guids(dev);
@ -531,17 +520,24 @@ fu_engine_add_local_release_metadata(FuEngine *self, FuRelease *release, GError
1, 1,
fu_release_get_version(release), fu_release_get_version(release),
NULL); NULL);
tags = xb_silo_query_with_context(self->silo, query, &context, &error_local); tags = xb_silo_query_with_context(self->silo,
self->query_tag_by_guid_version,
&context,
&error_local);
#else #else
if (!xb_query_bind_str(query, 0, guid, error)) { if (!xb_query_bind_str(self->query_tag_by_guid_version, 0, guid, error)) {
g_prefix_error(error, "failed to bind GUID: "); g_prefix_error(error, "failed to bind GUID: ");
return FALSE; return FALSE;
} }
if (!xb_query_bind_str(query, 1, fu_release_get_version(release), error)) { if (!xb_query_bind_str(self->query_tag_by_guid_version,
1,
fu_release_get_version(release),
error)) {
g_prefix_error(error, "failed to bind version: "); g_prefix_error(error, "failed to bind version: ");
return FALSE; return FALSE;
} }
tags = xb_silo_query_full(self->silo, query, &error_local); tags =
xb_silo_query_full(self->silo, self->query_tag_by_guid_version, &error_local);
#endif #endif
if (tags == NULL) { if (tags == NULL) {
if (g_error_matches(error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) || if (g_error_matches(error_local, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) ||
@ -3708,6 +3704,17 @@ fu_engine_create_silo_index(FuEngine *self, GError **error)
return FALSE; return FALSE;
} }
/* prepare tag query with bound GUID parameter */
self->query_tag_by_guid_version =
xb_query_new_full(self->silo,
"local/components/component[@merge='append']/provides/"
"firmware[text()=?]/../../releases/release[@version=?]/../../"
"tags/tag",
XB_QUERY_FLAG_OPTIMIZE,
error);
if (self->query_tag_by_guid_version == NULL)
return FALSE;
/* success */ /* success */
return TRUE; return TRUE;
} }
@ -8423,6 +8430,8 @@ fu_engine_finalize(GObject *obj)
g_object_unref(self->query_container_checksum1); g_object_unref(self->query_container_checksum1);
if (self->query_container_checksum2 != NULL) if (self->query_container_checksum2 != NULL)
g_object_unref(self->query_container_checksum2); g_object_unref(self->query_container_checksum2);
if (self->query_tag_by_guid_version != NULL)
g_object_unref(self->query_tag_by_guid_version);
if (self->coldplug_id != 0) if (self->coldplug_id != 0)
g_source_remove(self->coldplug_id); g_source_remove(self->coldplug_id);
if (self->approved_firmware != NULL) if (self->approved_firmware != NULL)