summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Withnall <philip@tecnocode.co.uk>2011-10-16 08:23:29 (GMT)
committerTravis Reitter <travis.reitter@collabora.co.uk>2011-10-17 18:43:25 (GMT)
commit5691fe6dcb5f8dac0a031c52994abbb6e1ad7d4d (patch)
tree42596d567d5552918955a90dd8075cf95ff48677
parenta9b8ec19dfb6c9f61f9f85d6ebfcf117bdc575a4 (diff)
downloadfolks-5691fe6dcb5f8dac0a031c52994abbb6e1ad7d4d.tar.gz
folks-5691fe6dcb5f8dac0a031c52994abbb6e1ad7d4d.tar.xz
core: Add support for object version migration in object cache files
Add the ability for the variant type used in object cache files to vary with the cache file version, and for object cache implementations to claim they don't support given versions. Helps: bgo#661475
-rw-r--r--backends/telepathy/lib/tpf-persona-store-cache.vala42
-rw-r--r--folks/object-cache.vala40
2 files changed, 62 insertions, 20 deletions
diff --git a/backends/telepathy/lib/tpf-persona-store-cache.vala b/backends/telepathy/lib/tpf-persona-store-cache.vala
index cf845de..9123a1a 100644
--- a/backends/telepathy/lib/tpf-persona-store-cache.vala
+++ b/backends/telepathy/lib/tpf-persona-store-cache.vala
@@ -57,20 +57,33 @@ internal class Tpf.PersonaStoreCache : Folks.ObjectCache<Tpf.Persona>
this._store = store;
}
- protected override VariantType get_serialised_object_type ()
+ protected override VariantType? get_serialised_object_type (
+ uint8 object_version)
{
- return new VariantType.tuple ({
- VariantType.STRING, // UID
- VariantType.STRING, // IID
- VariantType.STRING, // ID
- VariantType.STRING, // Protocol
- new VariantType.array (VariantType.STRING), // Groups
- VariantType.BOOLEAN, // Favourite?
- VariantType.STRING, // Alias
- VariantType.BOOLEAN, // In contact list?
- VariantType.BOOLEAN, // Is user?
- new VariantType.maybe (VariantType.STRING) // Avatar
- });
+ // Maximum version?
+ if (object_version == uint8.MAX)
+ {
+ object_version = this._FILE_FORMAT_VERSION;
+ }
+
+ if (object_version == 1)
+ {
+ return new VariantType.tuple ({
+ VariantType.STRING, // UID
+ VariantType.STRING, // IID
+ VariantType.STRING, // ID
+ VariantType.STRING, // Protocol
+ new VariantType.array (VariantType.STRING), // Groups
+ VariantType.BOOLEAN, // Favourite?
+ VariantType.STRING, // Alias
+ VariantType.BOOLEAN, // In contact list?
+ VariantType.BOOLEAN, // Is user?
+ new VariantType.maybe (VariantType.STRING) // Avatar
+ });
+ }
+
+ // Unsupported version
+ return null;
}
protected override uint8 get_serialised_object_version ()
@@ -119,7 +132,8 @@ internal class Tpf.PersonaStoreCache : Folks.ObjectCache<Tpf.Persona>
});
}
- protected override Tpf.Persona deserialise_object (Variant variant)
+ protected override Tpf.Persona deserialise_object (Variant variant,
+ uint8 object_version)
{
// Deserialise the persona
var uid = variant.get_child_value (0).get_string ();
diff --git a/folks/object-cache.vala b/folks/object-cache.vala
index db32020..9ead921 100644
--- a/folks/object-cache.vala
+++ b/folks/object-cache.vala
@@ -62,9 +62,14 @@ public abstract class Folks.ObjectCache<T> : Object
* If a smooth upgrade path is needed in future due to cache file format
* changes, this may be modified to take a version parameter.
*
+ * @param object_version the version of the object format to use, or
+ * `uint8.MAX` for the latest version
+ * @return variant type for that object version, or `null` if the version is
+ * unsupported
* @since 0.6.0
*/
- protected abstract VariantType get_serialised_object_type ();
+ protected abstract VariantType? get_serialised_object_type (
+ uint8 object_version);
/**
* Get the version of the variant type returned by
@@ -94,11 +99,13 @@ public abstract class Folks.ObjectCache<T> : Object
* {@link ObjectCache.get_serialised_object_type}.
*
* @param variant the serialised form to deserialise
+ * @param object_version the version of the object format to deserialise from
* @return the deserialised object
*
* @since 0.6.0
*/
- protected abstract T deserialise_object (Variant variant);
+ protected abstract T deserialise_object (Variant variant,
+ uint8 object_version);
/**
* Create a new cache instance using the given type ID and ID. This is
@@ -211,6 +218,18 @@ public abstract class Folks.ObjectCache<T> : Object
// Deserialise the variant according to the given version numbers
var variant_type =
this._get_cache_file_variant_type (wrapper_version, object_version);
+
+ if (variant_type == null)
+ {
+ warning ("Cache file '%s' was version %u of the object file " +
+ "format, which is not supported. The file was deleted.",
+ this._cache_file.get_path (), object_version,
+ this._FILE_FORMAT_VERSION);
+ yield this.clear_cache ();
+
+ return null;
+ }
+
var variant =
Variant.new_from_data<uint8[]> (variant_type, variant_data, false,
data);
@@ -257,7 +276,7 @@ public abstract class Folks.ObjectCache<T> : Object
for (uint i = 0; i < objects_variant.n_children (); i++)
{
var object_variant = objects_variant.get_child_value (i);
- var object = this.deserialise_object (object_variant);
+ var object = this.deserialise_object (object_variant, object_version);
objects.add (object);
}
@@ -286,7 +305,8 @@ public abstract class Folks.ObjectCache<T> : Object
debug ("Storing cache (type ID '%s', ID '%s') to file '%s'.",
this._type_id, this._id, this._cache_file.get_path ());
- var child_type = this.get_serialised_object_type ();
+ var child_type = this.get_serialised_object_type (uint8.MAX);
+ assert (child_type != null); // uint8.MAX should always be supported
Variant[] children = new Variant[objects.size];
// Serialise all the objects in the set
@@ -379,13 +399,21 @@ public abstract class Folks.ObjectCache<T> : Object
}
}
- private VariantType _get_cache_file_variant_type (uint8 wrapper_version,
+ private VariantType? _get_cache_file_variant_type (uint8 wrapper_version,
uint8 object_version)
{
+ var object_type = this.get_serialised_object_type (object_version);
+
+ if (object_type == null)
+ {
+ // Unsupported version
+ return null;
+ }
+
return new VariantType.tuple ({
VariantType.STRING, // Type ID
VariantType.STRING, // ID
- new VariantType.array (this.get_serialised_object_type ()) // Objects
+ new VariantType.array (object_type) // Objects
});
}