diff --git a/README.md b/README.md index e53616c..c872073 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Shoebox can be added easily to your Maven or Gradle project through Jitpack: ```kotlin fun main(args : Array) { val dir = Files.createTempDirectory("sb-") - val userStore = Store(dir.resolve("users"), User::class) + val userStore = Store(dir.resolve("users")) val usersByEmail = View(dir.resolve("usersByEmail"), userStore, viewBy = User::email) val usersByGender = View(dir.resolve("usersByGender"), userStore, viewBy = User::gender) diff --git a/build.gradle b/build.gradle index 2614734..88bf741 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ group 'com.github.sanity' -version '0.1.3' +version '0.1.4' buildscript { ext.kotlin_version = '1.1.0' diff --git a/src/main/kotlin/com/github/sanity/shoebox/Store.kt b/src/main/kotlin/com/github/sanity/shoebox/Store.kt index 2ac8357..5cf5766 100644 --- a/src/main/kotlin/com/github/sanity/shoebox/Store.kt +++ b/src/main/kotlin/com/github/sanity/shoebox/Store.kt @@ -9,19 +9,29 @@ import java.nio.file.Path import java.util.concurrent.ConcurrentHashMap import kotlin.reflect.KClass -/** - * Created by ian on 3/9/17. + /* * TODO: 1) Add a lockfile mechanism to prevent multiple JVMs or threads from * TODO: using the same directory * TODO: 2) Handle changes that occur to the filesystem which aren't initiated here * TODO: (then remove the previous lockfile mechanism) */ -class Store(val parentDirectory: Path, private val kc: KClass) { +/** + * Create a persistent string-indexed datastore + * + * @param T The type of the objects to store, these must be serializable with [Gson](https://github.com/google/gson), + * https://github.com/google/gson + * + * @param directory The path to a directory in which data will be stored, will be created if it doesn't already exist + * + **/ +inline fun Store(directory : Path) = Store(directory, T::class) + +class Store(val directory: Path, private val kc: KClass) { init { - Files.createDirectories(parentDirectory) + Files.createDirectories(directory) } internal val cache: LoadingCache = CacheBuilder.newBuilder().build( @@ -42,7 +52,7 @@ class Store(val parentDirectory: Path, private val kc: KClass) { /** * Return entries key-value pairs in this Store as an Iterable */ - val entries: Iterable> get() = Files.newDirectoryStream(parentDirectory) + val entries: Iterable> get() = Files.newDirectoryStream(directory) .mapNotNull { val fileKey = it.fileName.toString() KeyValue(fileKey, this[fileKey]!!) @@ -54,7 +64,7 @@ class Store(val parentDirectory: Path, private val kc: KClass) { fun remove(key: String) { val cachedValue: T? = cache.getIfPresent(key) - val filePath = parentDirectory.resolve(key) + val filePath = directory.resolve(key) if (Files.exists(filePath)) { val oldValue = cachedValue ?: load(key) if (oldValue != null) { @@ -68,7 +78,7 @@ class Store(val parentDirectory: Path, private val kc: KClass) { } private fun load(key: String): T? { - val filePath = parentDirectory.resolve(key) + val filePath = directory.resolve(key) if (Files.exists(filePath)) { val o = filePath.newBufferedReader().use { gson.fromJson(it, kc.javaObjectType) @@ -90,8 +100,8 @@ class Store(val parentDirectory: Path, private val kc: KClass) { } cache.put(key, value) if (value != previousValue) { - if (!parentDirectory.exists()) throw RuntimeException("Parent directory doesn't exist") - val filePath = parentDirectory.resolve(key) + if (!directory.exists()) throw RuntimeException("Parent directory doesn't exist") + val filePath = directory.resolve(key) filePath.newBufferedWriter().use { gson.toJson(value, kc.javaObjectType, it) } diff --git a/src/main/kotlin/com/github/sanity/shoebox/demos/one/one.kt b/src/main/kotlin/com/github/sanity/shoebox/demos/one/one.kt index 17e6438..51aa585 100644 --- a/src/main/kotlin/com/github/sanity/shoebox/demos/one/one.kt +++ b/src/main/kotlin/com/github/sanity/shoebox/demos/one/one.kt @@ -10,7 +10,7 @@ import java.nio.file.Files fun main(args : Array) { val dir = Files.createTempDirectory("sb-") - val userStore = Store(dir.resolve("users"), User::class) + val userStore = Store(dir.resolve("users")) val usersByEmail = View(dir.resolve("usersByEmail"), userStore, viewBy = User::email) val usersByGender = View(dir.resolve("usersByGender"), userStore, viewBy = User::gender)