1 /*
2 * Copyright 2022 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 * StorageConnection provides a way to read and write a particular type <T> of data.
21 * StorageConnections are created from [Storage] objects.
22 */
23 interface StorageConnection<T> : Closeable {
24
25 /**
26 * Creates a scope for reading to allow storage reads, and will try to obtain a read lock.
27 *
28 * @param block The block of code that is performed within this scope. Block will receive
29 * `locked` parameter which is true if the try lock succeeded.
30 * @throws IOException when there is an unrecoverable exception in reading.
31 */
readScopenull32 suspend fun <R> readScope(block: suspend ReadScope<T>.(locked: Boolean) -> R): R
33
34 /**
35 * Creates a write scope that guaranteed to only have one single writer, ensuring also that any
36 * reads within this scope have the most current data.
37 *
38 * @throws IOException when there is an unrecoverable exception in writing.
39 */
40 suspend fun writeScope(block: suspend WriteScope<T>.() -> Unit)
41
42 /**
43 * Provides a coordinator to guarantee data consistency across multiple threads and processes.
44 */
45 val coordinator: InterProcessCoordinator
46 }
47
48 /** The scope used for a read transaction. */
49 interface ReadScope<T> : Closeable {
50
51 /** Read the data <T> from the underlying storage. */
52 suspend fun readData(): T
53 }
54
55 /** The scope used for a write transaction. */
56 interface WriteScope<T> : ReadScope<T> {
57
58 /** Writes the data <T> to the underlying storage. */
writeDatanull59 suspend fun writeData(value: T)
60 }
61
62 /* Convenience method for opening a read scope, doing a single read, and closing the scope. */
63 suspend fun <T> StorageConnection<T>.readData(): T = readScope { readData() }
64
65 /* Convenience method for opening a write scope, doing a single write, and closing the scope. */
<lambda>null66 suspend fun <T> StorageConnection<T>.writeData(value: T) = writeScope { writeData(value) }
67