Skip to content

kwebio/shoebox

Repository files navigation

ShoeBox

ShoeBox is a Kotlin library for object persistence that supports the observer pattern so your code can be notified immediately when stored data is changed.

Motivation

While it is a standalone library, ShoeBox was created as a persistence layer for Kweb applications, motivated by the lack of a simple persistence mechanism that supports the observer pattern. The idea is to create a "bridge" library between Shoebox and Kweb that will allow "binding" of UI components to persistent state, also known as the data mapper pattern. Here is a video illustrating this idea for TornadoFX on Android.

To emphasize, however, Shoebox doesn't depend on Kweb and should be useful for many other things.

Features

  • Functionality similar to MutableMap
  • Add listeners for object addition, deletion, and modification
  • Fairly comprehensive unit tests
  • Lightweight, pulls in very few dependencies
  • Materialized views
    • Efficiently retrieve objects by any specified key derived from the object
    • Similar to database indexes, but also supporting the observer pattern
  • Currently data is stored as uncompressed files, serialized to JSON

Limitations

  • Not very space efficient for small objects as files take up at least 4K on many filesystems
  • Data isn't currently compressed
  • Directories can't be shared between different Shoebox instances, although this is planned
    • Once this is supported we can use shared filesystems to scale horizontally, limited only by the filesystem
  • Doesn't implement the MutableMap interface
    • Even though the semantics are very similar to MutableMap, it isn't currently implemented because we wanted to avoid loading all data into memory.
    • This is probably solvable through custom implementations of MutableSet, MutableEntry and other interfaces, and will probably be done before 1.0 is released.

Adding to your project

Shoebox can be added easily to your Maven or Gradle project through Jitpack:

Release

As of release 0.4.0 Shoebox uses Kotlin Serialization, so you will also need to add the serialization plugin to your project.

Simple Usage Example

fun main() {
    val dir = Files.createTempDirectory("sb-")
    val userStore = shoebox(dir.resolve("users"), User.serializer())
    val usersByEmail = userStore.view("usersByEmail", User::email)
    val usersByGender = userStore.view("usersByGender", User::gender)

    userStore["ian"] = User("Ian Clarke", "male", "ian@blah.com")
    userStore["fred"] = User("Fred Smith", "male", "fred@blah.com")
    userStore["sue"] = User("Sue Smith", "female", "sue@blah.com")

    println(usersByEmail["ian@blah.com"])   // [User(name=Ian Clarke, gender=male, email=ian@blah.com)]
    println(usersByGender["male"])          // [User(name=Ian Clarke, gender=male, email=ian@blah.com),
                                            // User(name=Fred Smith, gender=male, email=fred@blah.com)]
    // note: view["xx]" returns a set of values
    usersByGender.onAdd("male") { kv ->
        println("${kv.key} became male")
    }
    usersByGender.onRemove("male") { kv ->
        println("${kv.key} ceased to be male")
    }

    userStore["fred"] = userStore["fred"]!!.copy(gender = "female") // Prints "fred ceased to be male"
}

@Serializable data class User(val name : String, val gender : String, val email : String)

Documentation

About

ShoeBox is a Kotlin library for persistent data storage that supports views and the observer pattern. While often used with Kweb, it doesn't need to be.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages