Simple persistence layer for kotlin objects
| gradle/wrapper | ||
| src | ||
| test | ||
| .gitignore | ||
| build.gradle.kts | ||
| gradle.properties | ||
| gradlew | ||
| gradlew.bat | ||
| LICENSE | ||
| README.md | ||
| settings.gradle.kts | ||
Store
A simple persistence layer for arbitrary, typed and untyped kotlin data. It utilizes kotlinx-serialization and a flexible driver system.
Usage
Typed data
// Define some data
@Serializable
data class User(val id: Int, val name: String, val age: Int)
val store = typedStore<User>(
// Use FsStoreDriver to save data to disk
driver = FsStoreDriver(Path("./store")),
// Set a namespace to allow for segmentation while using the same driver
namespace = "typed:",
// Set your preferred serialization format
format = Json
)
// Persist your first data
val bob = User(id = 1, name = "bob", age = 30)
store["user.${user.id}"] = bob // thats it!
// access the data again
println(store["user.${user.id}"]!!.name) // -> "bob"
// check when it was last accessed
println(store.age("${user.id}")) // -> A epoch timestamp pointing to the last operation on Bob
// remove data
store -= "user.${user.id}"
// and clear all of it
store.clear()
Untyped data
val store = untypedStore(
// MemStoreDriver will not persist or write the data and simply hold it in memory until the store is GC-ed
driver = MemStoreDriver(),
// You can still segment it tho
namespace = "untyped:",
// And use another of your favourite data formats, thanks to ktx.serialization!
format = Toml,
)
// Persist some random data you have
store<String>["test.string"] = "Hello, World!"
store<Boolean>["test.bool"] = true
println(store<Boolean>["test.bool"]) // -> "true"
println(store<Boolean>["test.string"]) // this will fail!
// This also works with more complex elements as long as they are @Serializable
@Serializable
data class Person(val name: String)
@Serializable
data class Dog(val type: String, val name: String, val owner: Person)
store<Dog>["dog.stella"] = Dog("corgy", "Stella", Person("Dave"))
Defining your own Driver
A driver is a simple interface that handles the actual storage of the data that is being persisted. Drivers do not concern themselves with what data they get, simply with how they will store and access it
class ConcurrentMemDriver : StoreDriver {
private val map = ConcurrentHashMap<String, Pair<Long, String>>()
fun has(key: String): Boolean = map.contains(key)
fun remove(key: String): Boolean = map.remove(key) != null
fun age(key: String): Long? = map[key]?.first
fun get(key: String): String? = map[key]?.second
fun set(key: String, value: String) = map.set(key, value)
fun all(): Set<String> = map.keys
}
License
[MIT], go nuts