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.rxjava3;
18 
19 import io.reactivex.rxjava3.core.Completable;
20 import io.reactivex.rxjava3.core.Single;
21 
22 import org.jspecify.annotations.NonNull;
23 import org.jspecify.annotations.Nullable;
24 
25 /**
26  * Interface for migrations to DataStore. Methods on this migration ([shouldMigrate], [migrate]
27  * and [cleanUp]) may be called multiple times, so their implementations must be idempotent.
28  * These methods may be called multiple times if DataStore encounters issues when writing the
29  * newly migrated data to disk or if any migration installed in the same DataStore throws an
30  * Exception.
31  *
32  * If you're migrating from SharedPreferences see [SharedPreferencesMigration].
33  *
34  * @param <T> the exception type
35  */
36 public interface RxDataMigration<T> {
37 
38     /**
39      * Return whether this migration needs to be performed. If this returns false, no migration or
40      * cleanup will occur. Apps should do the cheapest possible check to determine if this migration
41      * should run, since this will be called every time the DataStore is initialized. This method
42      * may be run multiple times when any failure is encountered.
43      *
44      * Note that this will always be called before each call to [migrate].
45      *
46      * @param currentData the current data (which might already be populated from previous runs of
47      *                    this or other migrations). Only Nullable if the type used with DataStore
48      *                    is Nullable.
49      */
shouldMigrate(@ullable T currentData)50     @NonNull Single<Boolean> shouldMigrate(@Nullable T currentData);
51 
52     /**
53      * Perform the migration. Implementations should be idempotent since this may be called
54      * multiple times. If migrate fails, DataStore will not commit any data to disk, cleanUp will
55      * not be called, and the exception will be propagated back to the DataStore call that
56      * triggered the migration. Future calls to DataStore will result in DataMigrations being
57      * attempted again. This method may be run multiple times when any failure is encountered.
58      *
59      * Note that this will always be called before a call to [cleanUp].
60      *
61      * @param currentData the current data (it might be populated from other migrations or from
62      *                    manual changes before this migration was added to the app). Only
63      *                    Nullable if the type used with DataStore is Nullable.
64      * @return The migrated data.
65      */
migrate(@ullable T currentData)66     @NonNull Single<T> migrate(@Nullable T currentData);
67 
68     /**
69      * Clean up any old state/data that was migrated into the DataStore. This will not be called
70      * if the migration fails. If cleanUp throws an exception, the exception will be propagated
71      * back to the DataStore call that triggered the migration and future calls to DataStore will
72      * result in DataMigrations being attempted again. This method may be run multiple times when
73      * any failure is encountered.
74      */
cleanUp()75     @NonNull Completable cleanUp();
76 }
77