Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support migrations #29

Open
sindresorhus opened this issue Oct 8, 2019 · 4 comments
Open

Support migrations #29

sindresorhus opened this issue Oct 8, 2019 · 4 comments
Labels
enhancement New feature or request

Comments

@sindresorhus
Copy link
Owner

Sometimes you need to change a structure, for example, add a new property to a struct that is saved in user defaults. You can already do this without migrations by making the property optional, but that complicates a lot of code, and it doesn't work for more comprehensive changes.

I don't have a clear idea of how this would work, but I'm thinking the user would register migrations that run as early as possible at startup or on the first Defaults call if before that.

Defaults.migrations = [
	.Migration(version: "1.2.3") {
		// How to handle it here?
	}
]

I'm open to ideas.

@sindresorhus sindresorhus added the enhancement New feature or request label Oct 8, 2019
@koraykoska
Copy link
Contributor

koraykoska commented Oct 8, 2019

Just a few notes as I'm thinking about it...

Migrations typically handle two different cases:

First if you remove properties which existed before. This is not an issue for us as we save JSON strings and decoding them into a struct which removed a property will not cause any issues.

Second is adding properties which did not exist before. For this users would have to provide default values in case the already saved defaults do not include those properties already and decoding into their type would fail.
Default values can be any Codable type. We would just have to maintain those Migrations in memory and apply them before decoding.

The question is how. Codable and its decoders don't really have an easy way to access or modify parts of the resulting JSON.

@sindresorhus
Copy link
Owner Author

The question is how. Codable and its decoders don't really have an easy way to access or modify parts of the resulting JSON.

Indeed. That's the difficult part.

@sindresorhus
Copy link
Owner Author

sindresorhus commented Oct 22, 2019

I had an idea for this last night. We could give the user a Partial version of the original value in the migration callback, where all the properties are optionals. The benefit of that is that Codable will not throw is some properties are missing. This does not solve the problem if the type of a property changed, however.


I also saw an idea about a migrating decoder in the Swift forums: https://forums.swift.org/t/decodable-protocol-conformance-and-generics-how-to-dumb-down-a-conforming-type-to-call-the-right-implementation/29851/5


There are some good ideas in this article: http://merowing.info/2020/06/adding-support-for-versioning-and-migration-to-your-codable-models./

@koraykoska
Copy link
Contributor

koraykoska commented Oct 22, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants