1 /*
2  * Copyright 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.datastore.core
18 
19 /**
20  * Interface for migrations to DataStore. Methods on this migration ([shouldMigrate], [migrate] and
21  * [cleanUp]) may be called multiple times, so their implementations must be idempotent. These
22  * methods may be called multiple times if DataStore encounters issues when writing the newly
23  * migrated data to disk or if any migration installed in the same DataStore throws an Exception.
24  *
25  * If you're migrating from SharedPreferences see [SharedPreferencesMigration].
26  */
27 public interface DataMigration<T> {
28 
29     /**
30      * Return whether this migration needs to be performed. If this returns false, no migration or
31      * cleanup will occur. Apps should do the cheapest possible check to determine if this migration
32      * should run, since this will be called every time the DataStore is initialized. This method
33      * may be run multiple times when any failure is encountered.
34      *
35      * Note that this will always be called before each call to [migrate].
36      *
37      * Note that accessing any data from DataStore directly from inside this function will result in
38      * deadlock, since DataStore doesn't return data until all migrations complete.
39      *
40      * @param currentData the current data (which might already be populated from previous runs of
41      *   this or other migrations)
42      */
shouldMigratenull43     public suspend fun shouldMigrate(currentData: T): Boolean
44 
45     /**
46      * Perform the migration. Implementations should be idempotent since this may be called multiple
47      * times. If migrate fails, DataStore will not commit any data to disk, cleanUp will not be
48      * called, and the exception will be propagated back to the DataStore call that triggered the
49      * migration. Future calls to DataStore will result in DataMigrations being attempted again.
50      * This method may be run multiple times when any failure is encountered.
51      *
52      * Note that this will always be called before a call to [cleanUp].
53      *
54      * Note that accessing any data from DataStore directly from inside this function will result in
55      * deadlock, since DataStore doesn't return data until all migrations complete.
56      *
57      * @param currentData the current data (it might be populated from other migrations or from
58      *   manual changes before this migration was added to the app)
59      * @return The migrated data.
60      */
61     public suspend fun migrate(currentData: T): T
62 
63     /**
64      * Clean up any old state/data that was migrated into the DataStore. This will not be called if
65      * the migration fails. If cleanUp throws an exception, the exception will be propagated back to
66      * the DataStore call that triggered the migration and future calls to DataStore will result in
67      * DataMigrations being attempted again. This method may be run multiple times when any failure
68      * is encountered.
69      *
70      * This is useful for cleaning up files or data outside of DataStore and accessing any data from
71      * DataStore directly from inside this function will result in deadlock, since DataStore doesn't
72      * return data until all migrations complete.
73      */
74     public suspend fun cleanUp()
75 }
76