diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-02-04 13:58:33 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2014-02-04 13:58:33 +0000 |
commit | 9da576a7d1d6df02632f83e3d2613af1ab11fa17 (patch) | |
tree | 948f4ba4e2480e1ae75c375b0f9e34f6a846fe72 /src/mcd-storage.c | |
parent | a9eb0c74c190d172cf3d47fa264ab5fb4a30ce62 (diff) |
Opportunistically migrate accounts from untyped to typed Parameters
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=71093
Reviewed-by: Guillaume Desmottes <guillaume.desmottes@collabora.co.uk>
[also depend on new tp-glib for
tp_connection_manager_param_dup_variant_type -smcv]
Diffstat (limited to 'src/mcd-storage.c')
-rw-r--r-- | src/mcd-storage.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/mcd-storage.c b/src/mcd-storage.c index 3bd21de9..68ccd431 100644 --- a/src/mcd-storage.c +++ b/src/mcd-storage.c @@ -2060,3 +2060,124 @@ mcd_storage_dup_typed_parameters (McdStorage *self, return params; } + +/* See whether we can migrate the parameters from being stored without + * their types, to being stored with their types. + * Commit changes and return TRUE if anything happened. */ +gboolean +mcd_storage_maybe_migrate_parameters (McdStorage *self, + const gchar *account_name, + TpProtocol *protocol) +{ + McpAccountManager *api = MCP_ACCOUNT_MANAGER (self); + McpAccountStorage *plugin; + gchar **untyped_parameters = NULL; + gsize i; + gboolean ret = FALSE; + + plugin = g_hash_table_lookup (self->accounts, account_name); + g_return_val_if_fail (plugin != NULL, FALSE); + + /* If the storage backend can't store typed parameters, there's no point. */ + if (!mcp_account_storage_has_any_flag (plugin, account_name, + MCP_ACCOUNT_STORAGE_FLAG_STORES_TYPES)) + goto finally; + + untyped_parameters = mcp_account_storage_list_untyped_parameters ( + plugin, api, account_name); + + /* If there's nothing to migrate, there's also no point. */ + if (untyped_parameters == NULL || untyped_parameters[0] == NULL) + goto finally; + + DEBUG ("trying to migrate %s", account_name); + + for (i = 0; untyped_parameters[i] != NULL; i++) + { + const gchar *param_name = untyped_parameters[i]; + const TpConnectionManagerParam *param = tp_protocol_get_param (protocol, + param_name); + GError *error = NULL; + GVariantType *type = NULL; + GVariant *value; + McpAccountStorageSetResult res; + + if (param == NULL) + { + DEBUG ("cannot migrate parameter '%s': not supported by %s/%s", + param_name, tp_protocol_get_cm_name (protocol), + tp_protocol_get_name (protocol)); + goto next_param; + } + + type = tp_connection_manager_param_dup_variant_type (param); + + DEBUG ("Migrating parameter '%s' of type '%.*s'", + param_name, + (gint) g_variant_type_get_string_length (type), + g_variant_type_peek_string (type)); + + value = mcp_account_storage_get_parameter (plugin, api, + account_name, param_name, type, NULL); + + if (value == NULL) + { + DEBUG ("cannot migrate parameter '%s': %s #%d: %s", + param_name, g_quark_to_string (error->domain), error->code, + error->message); + g_error_free (error); + goto next_param; + } + + if (!g_variant_is_of_type (value, type)) + { + DEBUG ("trying to convert parameter from type '%s'", + g_variant_get_type_string (value)); + + /* consumes parameter */ + value = tp_variant_convert (value, type); + + if (value == NULL) + { + DEBUG ("could not convert parameter to desired type"); + goto next_param; + } + } + + res = mcp_account_storage_set_parameter (plugin, api, + account_name, param_name, value, MCP_PARAMETER_FLAG_NONE); + + switch (res) + { + case MCP_ACCOUNT_STORAGE_SET_RESULT_UNCHANGED: + /* it really ought to be CHANGED, surely? */ + DEBUG ("Tried to upgrade parameter %s but the " + "storage backend claims not to have changed it? " + "Not sure I really believe that", param_name); + /* fall through to the CHANGED case */ + + case MCP_ACCOUNT_STORAGE_SET_RESULT_CHANGED: + ret = TRUE; + break; + + case MCP_ACCOUNT_STORAGE_SET_RESULT_FAILED: + WARNING ("Failed to set parameter %s", param_name); + break; + + default: + WARNING ("set_parameter returned invalid result code %d " + "for parameter %s", res, param_name); + } + +next_param: + if (type != NULL) + g_variant_type_free (type); + } + + if (ret) + mcp_account_storage_commit (plugin, api, account_name); + +finally: + g_strfreev (untyped_parameters); + return ret; +} |