Kodein-DB is a Kotlin/Multiplatform embedded NoSQL database that works on JVM, Android, Kotlin/Native and iOS.

Overview

KODEIN-DI

Kodein-DB is a Kotlin/Multiplatform embedded NoSQL database that works on JVM, Android, Kotlin/Native and iOS. It is suited for client or mobile applications.

Kodein-DB allows you to:

  • Easily store, retrieve and query kotlin objects.
  • Stop caring about schema definitions.
  • Easily set up a new project.

Kodein-DB is a good choice because it:

  • proposes a very simple and readable DSL.
  • integrates nicely with Android and iOS.
  • offers very good performance.
  • is just Kotlin!

CAUTION: Under no circumstances should it be used in a server!

IMPORTANT

Kodein-DB is in beta.

Although, we do use Kodein-DB in production, this means we cannot ensure the library's correctness and stability. Therefore, we ask that you first try Kodein-DB in non-critical applications, and report any mis-behaviour you may encounter.

Example

.A simple example

().byIndex("lastName", "Doe").models() println(does.joinToString()) // Jane, John ">
val db = DB.open("path/to/db")

db.put(User("John", "Doe"))
db.put(User("Jane", "Doe"))
db.put(User("Someone", "Else"))

val does = db.find<User>().byIndex("lastName", "Doe").models()
println(does.joinToString()) // Jane, John

Kodein-DB documentation

Support

Contribute

Contributions are very welcome and greatly appreciated! The great majority of pull requests are eventually merged.

To contribute, simply fork the project on Github, fix whatever is itching you, and submit a pull request!

We are sure that this documentation contains typos, inaccuracies and language mistakes. If you feel like enhancing this document, you can propose a pull request that modifies the documentation documents. (Documentation is auto-generated from those).

Comments
  • java.lang.NoClassDefFoundError: Failed resolution of: Lorg/kodein/db/leveldb/jvm/LevelDBJvm;

    java.lang.NoClassDefFoundError: Failed resolution of: Lorg/kodein/db/leveldb/jvm/LevelDBJvm;

    When trying to run instrumented test on android. trying to test performance via android benchmarking but can't run test:

    java.lang.NoClassDefFoundError: Failed resolution of: Lorg/kodein/db/leveldb/jvm/LevelDBJvm;
    	at org.kodein.db.impl.data.DataDBJvm.getLdbFactory(DataDBJvm.kt:10)
    	at org.kodein.db.impl.data.AbstractDataDBFactory.open(AbstractDataDBFactory.kt:18)
    	at org.kodein.db.impl.data.AbstractDataDBFactory.open(AbstractDataDBFactory.kt:11)
    	at org.kodein.db.impl.model.AbstractModelDBFactory.open(AbstractModelDBFactory.kt:21)
    	at org.kodein.db.impl.model.AbstractModelDBFactory.open(AbstractModelDBFactory.kt:9)
    	at org.kodein.db.impl.AbstractDBFactory.open(AbstractDBFactory.kt:25)
    	at org.kodein.db.impl.AbstractDBFactory.open(AbstractDBFactory.kt:10)
    	at org.kodein.db.impl.DefaultKt.open(default.kt:7)
    
    opened by CarsonRedeye 14
  • Typesafe index metadata - with new index filter functions

    Typesafe index metadata - with new index filter functions

    Motivation

    I noticed that using the find function with indexes is powerful, but currently not typesafe. That is why I created this PR.

    Features

    It adds:

    • typesafe index creation using delegates
    • typesafe filters making use of this new index functionality
    • easy to use query functions accepting the new filters

    Examples

    Creating a model with various indices:

    @Serializable
    data class City(val name: String, val country: String, val postalCode: Int) : Metadata {
       override val id get() = postalCode
    
       val nameIndex by index(name)
       val countryIndex by index(country)
    
       val nameCountryPostalCodeIndex by index(name, country, postalCode)
    
       override fun indexes() = indexMapOf(nameIndex, countryIndex, nameCountryPostalCodeIndex)
    }
    

    Query the database for all french cities:

    db.find(City::countryIndex eq "France")
    // or to instantly get a list
    db.findModelList(City::countryIndex eq "France")
    

    It is typesafe because the following won't compile due to incompatible types:

    db.find(City::countryIndex eq 1234)
    

    ...and of course because you cannot query an index which does not exists this way (before that was possible because you just specified the name of the index as a String).

    Composite indexes are supported as well:

    db.findOneOrNull(City::nameCountryPostalCodeIndex eq Triple("Paris", "France", 75000))
    

    Tests

    I was not able to run the tests due to the following problem:

    A problem was found with the configuration of task ':ldb:lib:configureCrc32c-linux' (type 'CMakeConfigureTask').
    > File '/home/jakob/projects/Kodein-DB/ldb/lib/src/crc32c/CMakeLists.txt' specified for property 'cmakeListsTxt$buildSrc' does not exist.
    

    Could you do that for me?

    opened by jakobkmar 13
  • libkodein-leveldb-jni.dll: Can't find dependent libraries

    libkodein-leveldb-jni.dll: Can't find dependent libraries

    We are using Kodein-DB in our Android app and would like to write a console app (Kotlin) to read the DB on Windows in case we need to check what is in it from a support angle.

    When we run the following code we receive the following error

    val dbDirectory = "C:\\db\\Test"
        val db = DB.open(dbDirectory,
            KotlinxSerializer {
                +ReferenceDataResult.ReferenceDataResultSerializer
            },
            OpenPolicy.OpenOrCreate
        )
        println("Opened DB!") 
    
    Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\simon.burfield\AppData\Local\Kodein-DB\0.6.0-beta\libkodein-leveldb-jni.dll: Can't find dependent libraries
    	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1946)
    	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1828)
    	at java.lang.Runtime.load0(Runtime.java:810)
    	at java.lang.System.load(System.java:1088)
    	at org.kodein.db.leveldb.jvm.AbstractLevelDBJvmLoader.load(AbstractLevelDBJvmLoader.kt:77)
    	at org.kodein.db.leveldb.jvm.LevelDBJvm.<clinit>(LevelDBJvm.kt:28)
    	at org.kodein.db.impl.data.DataDBJvm.getLdbFactory(DataDBJvm.kt:10)
    	at org.kodein.db.impl.data.AbstractDataDBFactory.open(AbstractDataDBFactory.kt:18)
    	at org.kodein.db.impl.data.AbstractDataDBFactory.open(AbstractDataDBFactory.kt:11)
    	at org.kodein.db.impl.model.AbstractModelDBFactory.open(AbstractModelDBFactory.kt:29)
    	at org.kodein.db.impl.model.AbstractModelDBFactory.open(AbstractModelDBFactory.kt:9)
    	at org.kodein.db.impl.AbstractDBFactory.open(AbstractDBFactory.kt:25)
    	at org.kodein.db.impl.AbstractDBFactory.open(AbstractDBFactory.kt:10)
    	at org.kodein.db.impl.DefaultKt.open(default.kt:7)
    	at MainKt.main(main.kt:13)
    
    
    opened by SimonBurfield 12
  • Can we add encryption to the database?

    Can we add encryption to the database?

    After checking the talk at KotlinConf I found this project interesting to try.

    But in order to use it in production I would need to have ability to have the data encrypted when they are stored.

    I assume, that right now you don't have any kind of encryption implemented (e.g. via EncryptedFile, etc.) Can you advice if it's indeed the case?

    If so - can you advise if custom encryption could be defined already now or some changes would be required? On this slide I see, that there is an option to provide "custom middlewares" for transforming data. Do you know if it's suitable for this purpose?

    Basically we need to have an api which transforms un-encrypted bytes to encrypted bytes when we .put() and vise versa on .get().

    As example you can check this Encryption interface.

    opened by AlexTrotsenko 10
  • Kotlinx Serialization incompatibility when using Ktor

    Kotlinx Serialization incompatibility when using Ktor

    When using following versions

        const val kotlin = "1.4.30"
        const val kotlinCoroutines = "1.4.3-native-mt"
        const val ktor = "1.5.2"
        const val kotlinxSerialization = "1.0.1"
        const val kodein_db = "0.6.0-beta"
    

    I'm getting following when building iOS app. Are there any known combinations of versions that will allow 0.6.0-beta to work with Ktor atm?

    Unbound public symbol for public kotlinx.serialization.json/JsonDecoder.decodeSerializableElement|8042733237355806987[0] public kotlinx.serialization.json/JsonDecoder.decodeSerializableElement|8042733237355806987[0]
    Unbound public symbol for public kotlinx.serialization.json.internal/StreamingJsonDecoder.decodeNullableSerializableElement|7091057077819363828[0] public kotlinx.serialization.json.internal/StreamingJsonDecoder.decodeNullableSerializableElement|7091057077819363828[0]
    Unbound public symbol for public kotlinx.serialization.json.internal/StreamingJsonDecoder.decodeSerializableElement|8042733237355806987[0] public kotlinx.serialization.json.internal/StreamingJsonDecoder.decodeSerializableElement|8042733237355806987[0]
    Unbound public symbol for public kotlinx.serialization.internal/NamedValueDecoder.decodeNullableSerializableElement|7091057077819363828[0] public kotlinx.serialization.internal/NamedValueDecoder.decodeNullableSerializableElement|7091057077819363828[0]
    Unbound public symbol for public kotlinx.serialization.internal/NamedValueDecoder.decodeSerializableElement|8042733237355806987[0] public kotlinx.serialization.internal/NamedValueDecoder.decodeSerializableElement|8042733237355806987[0]
    
    opened by joreilly 9
  • deleteById does not work

    deleteById does not work

    I am calling DB.deleteById<M>(id) but when I call DB.getById<M>(id) I get the object back like it was not deleted. However, if I delete like that:

    val key = DB.keyById<M>(id)
    persistentDB.delete(key)
    

    all works as expected. Am I doing something wrong or there is a bug?

    opened by iMrTidy 5
  • NoSuchMethodError: java.nio.ByteBuffer.position(I)Ljava/nio/ByteBuffer;

    NoSuchMethodError: java.nio.ByteBuffer.position(I)Ljava/nio/ByteBuffer;

    Hello, I have an issue with Kodein DB 0.8.0-beta

    The code is at https://github.com/LouisCAD/kotlin-libraries-playground

    It works locallly on macOS but not on the CI so I'm a bit at a lost

    The stacktrace is here https://scans.gradle.com/s/qztqjpf2oc23u/console-log?anchor=180

    Or here https://github.com/LouisCAD/kotlin-libraries-playground/pull/103/checks?check_run_id=2658798807

    opened by jmfayard 3
  • Flush a table content

    Flush a table content

    Hi,

    I'm trying to figure out how to flush the content of a table and I couldn't find the answer in the documentation. Is there an equivalent to:

    localDB.deleteAll<SomeModelClass>()
    

    Tried

    localDB.delete(localDB.find<SomeModelClass>().all().key())
    

    Get the error java.lang.IllegalStateException: Cursor is not valid

    opened by ggimes 3
  • kodein-leveldb-jni-macos not published

    kodein-leveldb-jni-macos not published

    Hello I tried kodein-db here https://github.com/LouisCAD/kotlin-libraries-playground/commit/9165f6ecfc148a2d42335bd8b7cb6fbc951cc538

    I noted an error in the doc. It talks about @Index but it seems to be @Indexed here https://docs.kodein.org/kodein-db/0.2.0/core/defining-data-model.html

    My main problem is that my program fails on a mac with

    Caused by: java.lang.IllegalStateException: Could not load kodein-leveldb-jni-macos. Have you added it to the classpath?

    The thing is kodein-leveldb-jni-linux has been published there, but not kodein-leveldb-jni-macos (or windows for that matter)

    https://dl.bintray.com/kodein-framework/Kodein-DB/org/kodein/db/

    opened by jmfayard 3
  • Update docs for required argument of `find`

    Update docs for required argument of `find`

    find() has a required argument of type KClass, so find<User>() doesn't work since it has no arguments.

    An alternative solution, of course, would be to change the find() function to match the docs if that is the desired behavior. I'm not sure if the type argument is used in a way that can't be done with just the generic M. If not, then the argument can just be removed in favor of the generic type. Otherwise I don't know an immediate solution offhand.

    opened by Minirogue 3
  • 'put' method crashes when called from a suspend function in iOS

    'put' method crashes when called from a suspend function in iOS

    I'm currently using version 0.9.0-beta with kotlin version 1.5.30.

    while trying to use 'put' inside a suspend function, I get the following crash on iOS (debug)

    Attached below is the stack trace.

    Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlin.collections.HashMap@2325028
    Failed to read dyld info for process 86768 (5)
        at 0   KmmDesignTests                      0x0000000109b019c1 kfun:kotlin.Throwable#<init>(kotlin.String?){} + 97
        at 1   KmmDesignTests                      0x0000000109afa28d kfun:kotlin.Exception#<init>(kotlin.String?){} + 93
        at 2   KmmDesignTests                      0x0000000109afa4ad kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 93
        at 3   KmmDesignTests                      0x0000000109b36e1d kfun:kotlin.native.concurrent.InvalidMutabilityException#<init>(kotlin.String){} + 93
        at 4   KmmDesignTests                      0x0000000109b3842f ThrowInvalidMutabilityException + 431
        at 5   KmmDesignTests                      0x000000010ab12450 MutationCheck + 128
        at 6   KmmDesignTests                      0x0000000109b16fd2 kfun:kotlin.collections.HashMap.<set-length>#internal + 82
        at 7   KmmDesignTests                      0x0000000109b1bf36 kfun:kotlin.collections.HashMap#addKey(1:0){}kotlin.Int + 1270
        at 8   KmmDesignTests                      0x0000000109b2613f kfun:kotlin.collections.HashSet#add(1:0){}kotlin.Boolean + 207
        at 9   KmmDesignTests                      0x000000010a338634 kfun:org.kodein.db.leveldb.PlatformCloseable.Handler#add(org.kodein.db.leveldb.PlatformCloseable){} + 484
        at 10  KmmDesignTests                      0x000000010a33639b kfun:org.kodein.db.leveldb.PlatformCloseable#<init>(kotlin.String;org.kodein.db.leveldb.PlatformCloseable.Handler?;org.kodein.db.leveldb.LevelDB.Options){} + 1099
        at 11  KmmDesignTests                      0x000000010a3879c1 kfun:org.kodein.db.leveldb.native.PointerBound#<init>(kotlinx.cinterop.CPointer<1:0>?;kotlin.String;org.kodein.db.leveldb.PlatformCloseable.Handler?;org.kodein.db.leveldb.LevelDB.Options){} + 193
        at 12  KmmDesignTests                      0x000000010a380af2 kfun:org.kodein.db.leveldb.native.LevelDBNative.NativeBytes#<init>(kotlinx.cinterop.CPointer<kotlinx.cinterop.ByteVarOf<kotlin.Byte>>;kotlin.Int;org.kodein.db.leveldb.PlatformCloseable.Handler;org.kodein.db.leveldb.LevelDB.Options;org.kodein.memory.io.Memory){} + 226
        at 13  KmmDesignTests                      0x000000010a380dc1 kfun:org.kodein.db.leveldb.native.LevelDBNative.NativeBytes#<init>(kotlinx.cinterop.CPointer<kotlinx.cinterop.ByteVarOf<kotlin.Byte>>;kotlin.Int;org.kodein.db.leveldb.PlatformCloseable.Handler;org.kodein.db.leveldb.LevelDB.Options;org.kodein.memory.io.Memory?;kotlin.Int;kotlin.native.internal.DefaultConstructorMarker?){} + 609
        at 14  KmmDesignTests                      0x000000010a3829c7 kfun:org.kodein.db.leveldb.native.LevelDBNative#get(org.kodein.memory.io.ReadMemory;org.kodein.db.leveldb.LevelDB.ReadOptions){}org.kodein.memory.io.Allocation? + 1847
        at 15  KmmDesignTests                      0x000000010a3c5f1f kfun:org.kodein.db.impl.kv.KeyValueDBImpl#get(org.kodein.memory.io.ReadMemory;kotlin.Array<out|org.kodein.db.Options.Get>...){}org.kodein.memory.io.Allocation? + 543
        at 16  KmmDesignTests                      0x000000010a3d4178 kfun:org.kodein.db.impl.model.ModelDBImpl#getTypeId(org.kodein.memory.io.ReadMemory;kotlin.Boolean){}kotlin.Int + 3672
        at 17  KmmDesignTests                      0x000000010a370761 kfun:org.kodein.db.model.ModelTypeMatcher#getTypeId$default(org.kodein.memory.io.ReadMemory;kotlin.Boolean;kotlin.Int){}kotlin.Int + 257
        at 18  KmmDesignTests                      0x000000010a3dc6b3 kfun:org.kodein.db.impl.model.ModelKeyMakerModule#keyFrom(0:0;kotlin.Array<out|org.kodein.db.Options.Puts>...){0§<kotlin.Any>}org.kodein.db.Key<0:0> + 1427
        at 19  KmmDesignTests                      0x000000010a3f4891 kfun:org.kodein.db.impl.model.cache.CachedModelDB#put(0:0;kotlin.Array<out|org.kodein.db.Options.DirectPut>...){0§<kotlin.Any>}org.kodein.db.KeyAndSize<0:0> + 2945
        at 20  KmmDesignTests                      0x000000010a38e1ed kfun:org.kodein.db.impl.DBImpl#put(0:0;kotlin.Array<out|org.kodein.db.Options.DirectPut>...){0§<kotlin.Any>}org.kodein.db.Key<0:0> + 877
        at 21  KmmDesignTests                      0x000000010a340268 kfun:org.kodein.db.DB#put(0:0;kotlin.Array<out|org.kodein.db.Options.Puts>...){0§<kotlin.Any>}org.kodein.db.Key<0:0> + 920
        at 22  KmmDesignTests                      0x000000010a348ef8 kfun:org.kodein.db.DBWrite#put(0:0){0§<kotlin.Any>}org.kodein.db.Key<0:0> + 920
        at 23  KmmDesignTests                      0x000000010a43bfd5 kfun:live.texel.engagement.common#freezePut__at__org.kodein.db.DB(0:0){0§<kotlin.Any>}org.kodein.db.Key<0:0> + 325
        at 24  KmmDesignTests                      0x000000010a50a1a4 
    
    opened by YanivSos 2
  • ConcurrentModificationException on find

    ConcurrentModificationException on find

    Hi, I'm developing an android application using kodein-db and I have been using this code to get all results from MyData class:

    val list = db.find(MyData::class).all().useModels { it.toList() }
    

    The data is updated frequently by other threads and sometimes I get a java.util.ConcurrentModificationException

    
    java.util.ConcurrentModificationException
            at java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:757)
            at java.util.LinkedHashMap$LinkedEntryIterator.next(LinkedHashMap.java:790)
            at java.util.LinkedHashMap$LinkedEntryIterator.next(LinkedHashMap.java:790)
            at java.util.HashMap.putMapEntries(HashMap.java:511)
            at java.util.HashMap.putAll(HashMap.java:784)
            at org.kodein.db.impl.model.cache.ModelCacheImpl.renewInternals(ModelCacheImpl.kt:149)
            at org.kodein.db.impl.model.cache.ModelCacheImpl.copyIfNeeded(ModelCacheImpl.kt:159)
            at org.kodein.db.impl.model.cache.ModelCacheImpl.access$copyIfNeeded(ModelCacheImpl.kt:12)
            at org.kodein.db.impl.model.cache.ModelCacheImpl$getOrRetrieveEntry$1.invoke(ModelCacheImpl.kt:128)
            at org.kodein.db.impl.model.cache.ModelCacheImpl$getOrRetrieveEntry$1.invoke(ModelCacheImpl.kt:123)
            at org.kodein.db.impl.model.cache.ModelCacheImpl$getOrRetrieveEntry$2.invoke(ModelCacheImpl.kt:291)
            at org.kodein.db.impl.model.cache.ModelCacheImpl$getOrRetrieveEntry$2.invoke(ModelCacheImpl.kt:143)
            at org.kodein.db.impl.model.cache.ModelCacheImpl.getOrRetrieveEntry(ModelCacheImpl.kt:123)
            at org.kodein.db.impl.model.cache.ModelCacheImpl.getOrRetrieveEntry(ModelCacheImpl.kt:143)
            at org.kodein.db.impl.model.cache.CachedModelCursor.model(CachedModelCursor.kt:23)
            at org.kodein.db.impl.CursorImpl.model(CursorImpl.kt:13)
            at org.kodein.db.CursorKt$asModelSequence$$inlined$asSequence$1.invokeSuspend(Cursor.kt:47)
            at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
            at kotlin.sequences.SequenceBuilderIterator.hasNext(SequenceBuilder.kt:140)
            at kotlin.sequences.SequencesKt___SequencesKt.toCollection(_Sequences.kt:786)
            at kotlin.sequences.SequencesKt___SequencesKt.toMutableList(_Sequences.kt:816)
            at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:807)
            at xxxx.MyDb.getAll(MyDb.kt:43)
            at xxxx.SomeDataSource.getAll(SomeDataSource.kt:18)
            at xxxx.UiListController$init$1$invokeSuspend$$inlined$collect$1.emit(Collect.kt:135)
            at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:62)
            at kotlinx.coroutines.flow.FlowKt__ChannelsKt.access$emitAllImpl$FlowKt__ChannelsKt(Channels.kt:1)
            at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:14)
            at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
            at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
            at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
            at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
            at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
            at android.os.Handler.handleCallback(Handler.java:790)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:164)
            at android.app.ActivityThread.main(ActivityThread.java:6494)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    
    

    Is this expected and should I just try again? Or should I use some other way of getting all entries?

    opened by tepel 1
  • Keys don't encode polymorphic type

    Keys don't encode polymorphic type

    Say I had this polymorphic type

    sealed interface SavedListElement : Metadata {}
    class SavedWorkRef : SavedListElement {
      override val id: String
    }
    class SavedChapterRef : SavedListElement {
      override val id: String
    }
    

    and this definition

    TypeTable {
        root<SavedListElement>()
            .sub<SavedWorkRef>()
            .sub<SavedChapterRef>()
    }
    

    Then I get

    Screen Shot 2022-01-08 at 10 40 50 pm

    Where the keys are the same for both concrete types as long as the ID is the same.

    This means I can't store the store different types given the same key, is that normal? e.g.

    val id = UUID.randomUUID().toString()
    val a = SavedChapterRef(id)
    val b = SavedWorkRef(id)
    db.put(a)
    println(db.getById<SavedWorkRef>(b.id))
    

    Prints out

    SavedChapterRef(id=56652680-31d2-4a13-81d9-5671e961f0ad)
    
    opened by gnawf 0
  • NoSuchMethodError: void ModelCache$Entry$Cached.<init>(java.lang.Object, int, int)

    NoSuchMethodError: void ModelCache$Entry$Cached.(java.lang.Object, int, int)

    Getting this exception when upgrading from 0.8.1 to 0.9.0 on Desktop JVM target

    Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: 'void org.kodein.db.model.cache.ModelCache$Entry$Cached.<init>(java.lang.Object, int, int)'
    	at org.kodein.db.impl.model.cache.ModelCacheImpl$getOrRetrieveEntry$1.invoke(ModelCacheImpl.kt:133)
    	at org.kodein.db.impl.model.cache.ModelCacheImpl$getOrRetrieveEntry$1.invoke(ModelCacheImpl.kt:123)
    	at org.kodein.db.impl.model.cache.ModelCacheImpl$getOrRetrieveEntry$2.invoke(ModelCacheImpl.kt:291)
    	at org.kodein.db.impl.model.cache.ModelCacheImpl$getOrRetrieveEntry$2.invoke(ModelCacheImpl.kt:143)
    	at org.kodein.db.impl.model.cache.ModelCacheImpl.getOrRetrieveEntry(ModelCacheImpl.kt:123)
    	at org.kodein.db.impl.model.cache.ModelCacheImpl.getOrRetrieveEntry(ModelCacheImpl.kt:143)
    	at org.kodein.db.impl.model.cache.CachedModelCursor.model(CachedModelCursor.kt:23)
    	at org.kodein.db.impl.CursorImpl.model(CursorImpl.kt:13)
    	at org.kodein.db.CursorKt$asModelSequence$$inlined$asSequence$1.invokeSuspend(Cursor.kt:47)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlin.sequences.SequenceBuilderIterator.hasNext(SequenceBuilder.kt:140)
    	at kotlin.sequences.TakeSequence$iterator$1.hasNext(Sequences.kt:421)
    	at kotlin.sequences.SequencesKt___SequencesKt.toCollection(_Sequences.kt:786)
    	at kotlin.sequences.SequencesKt___SequencesKt.toMutableList(_Sequences.kt:816)
    	at kotlin.sequences.SequencesKt___SequencesKt.toList(_Sequences.kt:807)
    

    Code was

            return db
                .find<Obj>()
                .use { cursor ->
                    cursor.asModelSequence(reverse = true)
                        .toList()
                }
    

    Also, do a new release? The functions in commit https://github.com/Kodein-Framework/Kodein-DB/commit/f2909cde1c5e3ce7d747cb417804fe784020e9c4 aren't available in 0.9.0-beta

    opened by gnawf 0
  • [Gradle / shadowJar] Could not resolve org.kodein.db:kodein-leveldb:0.8.1-beta.

    [Gradle / shadowJar] Could not resolve org.kodein.db:kodein-leveldb:0.8.1-beta.

    Hello, I'm creating Minecraft's mod, and I want to use kodein-db for recording. But gradle shadowJar doesn't work.

    I appreciate your help and your work.

    Here's an error message and build.gradle.

    Gradle: v7.2

    • Error message of gradle shadowJar
    Could not determine the dependencies of task ':shadowJar'.
    > Could not resolve all dependencies for configuration ':shadow'.
       > Could not resolve org.kodein.db:kodein-leveldb:0.8.1-beta.
         Required by:
             project : > org.kodein.db:kodein-db-jvm:0.8.1-beta
             project : > org.kodein.db:kodein-leveldb-jni-jvm:0.8.1-beta > org.kodein.db:kodein-leveldb-jni-jvm-linux:0.8.1-beta
             project : > org.kodein.db:kodein-leveldb-jni-jvm:0.8.1-beta > org.kodein.db:kodein-leveldb-jni-jvm-macos:0.8.1-beta
             project : > org.kodein.db:kodein-leveldb-jni-jvm:0.8.1-beta > org.kodein.db:kodein-leveldb-jni-jvm-windows:0.8.1-beta
          > Cannot choose between the following variants of org.kodein.db:kodein-leveldb:0.8.1-beta:
              - debugRuntimeElements-published
              - jvmRuntimeElements-published
              - releaseRuntimeElements-published
            All of them match the consumer attributes:
              - Variant 'debugRuntimeElements-published' capability org.kodein.db:kodein-leveldb:0.8.1-beta:
                  - Unmatched attributes:
                      - Provides com.android.build.api.attributes.BuildTypeAttr 'debug' but the consumer didn't ask for it
                      - Provides com.android.build.api.attributes.VariantAttr 'debug' but the consumer didn't ask for it
                      - Provides org.gradle.status 'release' but the consumer didn't ask for it
                      - Provides org.gradle.usage 'java-runtime' but the consumer didn't ask for it
                      - Provides org.jetbrains.kotlin.platform.type 'androidJvm' but the consumer didn't ask for it
              - Variant 'jvmRuntimeElements-published' capability org.kodein.db:kodein-leveldb:0.8.1-beta:
                  - Unmatched attributes:
                      - Provides org.gradle.libraryelements 'jar' but the consumer didn't ask for it
                      - Provides org.gradle.status 'release' but the consumer didn't ask for it
                      - Provides org.gradle.usage 'java-runtime' but the consumer didn't ask for it
                      - Provides org.jetbrains.kotlin.platform.type 'jvm' but the consumer didn't ask for it
              - Variant 'releaseRuntimeElements-published' capability org.kodein.db:kodein-leveldb:0.8.1-beta:
                  - Unmatched attributes:
                      - Provides com.android.build.api.attributes.BuildTypeAttr 'release' but the consumer didn't ask for it
                      - Provides com.android.build.api.attributes.VariantAttr 'release' but the consumer didn't ask for it
                      - Provides org.gradle.status 'release' but the consumer didn't ask for it
                      - Provides org.gradle.usage 'java-runtime' but the consumer didn't ask for it
                      - Provides org.jetbrains.kotlin.platform.type 'androidJvm' but the consumer didn't ask for it
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
    
    • build.gradle
    buildscript {
        ext.kotlin_version = '1.5.21'
        repositories {
            jcenter()
            mavenCentral()
            maven { url = 'https://maven.minecraftforge.net' }
            maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
        }
        dependencies {
            classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.+', changing: true
            classpath group: 'org.spongepowered', name: 'mixingradle', version: '0.7-SNAPSHOT'
            classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        }
    }
    
    plugins {
        id 'com.github.johnrengelman.shadow' version '7.1.0'
    }
    
    apply plugin: 'net.minecraftforge.gradle'
    apply plugin: 'kotlin'
    apply plugin: 'org.spongepowered.mixin'
    //Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
    apply plugin: 'com.github.johnrengelman.shadow'
    apply plugin: 'java'
    
    version = "0.1.0-1.16.3"
    group = "com.kyokoyama" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
    archivesBaseName = "joyflick"
    
    sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = compileJava.targetCompatibility = '1.8' // Need this here so eclipse task generates correctly.
    
    mixin {
        add sourceSets.main, "joyflick.refmap.json"
        add sourceSets.main, "expmanager.refmap.json"
    }
    
    minecraft {
        mappings channel: 'snapshot', version: '20201028-1.16.3'
        
        accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg')
    
        runs {
            client {
                workingDirectory project.file('run')
                property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
                property 'forge.logging.console.level', 'debug'
                arg "-mixin.config=expmanager.mixins.json"
                arg "-mixin.config=joyflick.mixins.json"
                mods {
                    joyflick {
                        source sourceSets.main
                    }
                }
            }
    
            server {
                workingDirectory project.file('run')
                property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
                property 'forge.logging.console.level', 'debug'
                arg "-mixin.config=expmanager.mixins.json"
                arg "-mixin.config=joyflick.mixins.json"
                mods {
                    joyflick {
                        source sourceSets.main
                    }
                }
            }
    
            data {
                workingDirectory project.file('run')
                property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
                property 'forge.logging.console.level', 'debug'
                args '--mod', 'joyflick', '--all', '--output', file('src/generated/resources/')
                mods {
                    joyflick {
                        source sourceSets.main
                    }
                }
            }
        }
    }
    
    sourceSets.main.resources { srcDir 'src/generated/resources' }
    
    repositories {
        maven {
            // location of the maven that hosts JEI files
            name = "Progwml6 maven"
            url = "https://dvs1.progwml6.com/files/maven/"
        }
        maven {
            // location of a maven mirror for JEI files, as a fallback
            name = "ModMaven"
            url = "https://modmaven.k-4u.nl"
        }
        maven {
            url = "https://www.cursemaven.com"
        }
        mavenCentral()
        maven {
            name = 'kotlinforforge'
            url = 'https://thedarkcolour.github.io/KotlinForForge/'
        }
    }
    
    allprojects {
        repositories {
            google()
            maven { url = "https://jitpack.io" }
        }
    }
    
    //configurations {
    //    shade
    //    shadow
    //}
    
    dependencies {
        minecraft 'net.minecraftforge:forge:1.16.3-34.1.42'
    //    implementation fg.deobf("mezz.jei:jei-1.16.3:7.6.0.51")
        runtimeOnly fg.deobf("curse.maven:controllable-317269:3335987")
        compileOnly fg.deobf("curse.maven:controllable-317269:3335987")
    //    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
        runtimeOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
        compileOnly "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
    //    implementation 'thedarkcolour:kotlinforforge:1.15.1'
        runtimeOnly 'thedarkcolour:kotlinforforge:1.15.1'
        compileOnly 'thedarkcolour:kotlinforforge:1.15.1'
    
        // reflection
        shadow "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
    //    shade "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
    
        shadow "com.github.KaiseiYokoyama:JoyFlickMODRecord:v1.11"
    //    shade "com.github.KaiseiYokoyama:JoyFlickMODRecord:v1.11"
    
        // kodein-db
    
        shadow "org.kodein.db:kodein-db-jvm:0.8.1-beta"
        shadow "org.kodein.db:kodein-db-serializer-kotlinx:0.8.1-beta"
        shadow "org.kodein.db:kodein-leveldb-jni-jvm:0.8.1-beta"
    
    //    shade "org.kodein.db:kodein-db-jvm:0.8.1-beta"
    //    shade "org.kodein.db:kodein-db-serializer-kotlinx:0.8.1-beta"
    //    shade "org.kodein.db:kodein-leveldb-jni-jvm:0.8.1-beta"
    
        shadow "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1"
        shadow "org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.2.1"
        shadow "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2"
        shadow "org.jsoup:jsoup:1.14.2"
        shadow 'org.jetbrains.kotlinx:kotlinx-datetime:0.3.0'
    
    //    shade "org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.1"
    //    shade "org.jetbrains.kotlinx:kotlinx-serialization-protobuf:1.2.1"
    //    shade "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2"
    //    shade "org.jsoup:jsoup:1.14.2"
    //    shade 'org.jetbrains.kotlinx:kotlinx-datetime:0.3.0'
    
        testImplementation 'org.junit.jupiter:junit-jupiter:5.5.2'
    }
    
    jar {
        manifest {
            attributes([
                    "Specification-Title"     : "JoyFlick",
                    "Specification-Vendor"    : "Kaisei Yokoyama",
                    "Specification-Version"   : "1",
                    "Implementation-Title"    : project.name,
                    "Implementation-Version"  : "${version}",
                    "Implementation-Vendor"   : "Kaisei Yokoyama",
                    "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
                    "Signing-Fingerprint"     : project.hasProperty('fingerprint') ? project.property('fingerprint') : 'unsigned',
                    "MixinConfigs"            : "joyflick.mixins.json,expmanager.mixins.json"
            ])
        }
    }
    
    shadowJar {
        archiveClassifier.set('')
    
        project.configurations.shadow.setCanBeResolved(true)
        configurations = [project.configurations.shadow]
        duplicatesStrategy = DuplicatesStrategy.EXCLUDE
    }
    
    // https://qiita.com/MirrgieRiana/items/a006a0fbe21e30a2f7a2
    reobf {
        shadowJar {}
    }
    tasks.shadowJar.finalizedBy('reobfShadowJar')
    
    artifacts {
        archives shadowJar
    }
    
    test {
        // JUnit platform を使う設定
        useJUnitPlatform()
    
        testLogging {
            // テスト時の標準出力と標準エラー出力を表示する
            showStandardStreams true
            // イベントを出力する (TestLogEvent)
            events 'started', 'skipped', 'passed', 'failed'
            // 例外発生時の出力設定 (TestExceptionFormat)
            exceptionFormat 'full'
        }
    }
    
    //Properties keyStoreProperties = new Properties()
    //File file = new File("C:\\dev\\keystore.properties")
    //if (file.exists()) {
    //    InputStream ins = new FileInputStream(file)
    //    keyStoreProperties.load(ins)
    //    ins.close()
    //}
    
    compileKotlin {
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
    compileTestKotlin {
        kotlinOptions {
            jvmTarget = "1.8"
        }
    }
    
    opened by KaiseiYokoyama 0
  • Exception when accessing from multiple Threads

    Exception when accessing from multiple Threads

    Hello, I'm not sure if the library is supposed to be thread safe, but I'm having an issue when accessing the database from multiple threads. In particular, the problem seems to be in this section of the library:

          class OfField(override val member: Field) : ValueGetter() {
               override fun get(model: Any): Any? {
                   @Suppress("DEPRECATION") val wasAccessible = member.isAccessible
                   if (!wasAccessible) member.isAccessible = true
                   try {
                       return member.get(model)
                   } finally {
                       if (!wasAccessible) member.isAccessible = false
                   }
               }
           }
    

    Here the access is not protected by a mutex, so it happens that a Thread tries to get the member while isAccessible has been set to false by another Thread

    opened by PaoloConte 2
Releases(0.9.0-beta)
  • 0.9.0-beta(Jul 20, 2021)

    • API

      • Better event bus API with Kotlinx Coroutines Flow support.
    • CORE

      • The Model Cache now checks for mutations between insertion & retrieval (with hashcode). This is far from foolproof, but it's something!
    Source code(tar.gz)
    Source code(zip)
  • 0.8.1-beta(Jun 2, 2021)

  • 0.8.0-beta(May 19, 2021)

    • API

      • Support encryption (see documentation).
      • org.kodein.db.model.*Primitive types are deprecated (you should create your won model).
      • Support for multiple value in the same index (which is different from composite value - see documentation).
      • Support for associatedModel in IndexCursor (see documentation).
      • Operation options are now specialized for each operation (Options.Read and Options.Write are deprecated).
    • CORE

      • Kotlin 1.5
      • Kodein Memory 0.10.0
      • Kodein Log 0.11.0
      • KotlinX Atomic Fu 0.16.1
      • KotlinX Serialization 1.2.0
      • Windows JNI DLL is now built with Visual Studio.
    • INTERNALS

      • New version of Index value & ref value storage. This is backward compatible, and previous version is handled correctly.
    Source code(tar.gz)
    Source code(zip)
  • 0.6.1-beta(Mar 15, 2021)

  • 0.6.0-beta(Mar 1, 2021)

  • 0.5.0-beta(Jan 8, 2021)

    • BREAKING CHANGES

      • Value.ofAny and Value.ofAll are removed in favour of ModelDB.valueOf and ModelDB.valueOfAll (to allow the use of ValueConverters). This change should only affect middlewares as regular users should use models instead of values.
      • Removed the Index type as Set<Index> is less correct than Map<String, Any> since there can be no two indexes with the same name.
      • Because of the transient dependency to KotlinX-DateTime by the new version of Kodein-Log, the KotlinX maven repositories is temporarily needed (https://kotlin.bintray.com/kotlinx).
    • API

      • DBListener now receives Key<M> instead of Key<*>.
      • Added DB.getById & DB.deleteById.
      • Introducing ValueConverter, which allows to add to the database new types that can be used as values (i.e used in IDs or indexes). See documentation.
    • ANDROID

      • Fixed native compilation.
    • CORE

      • Kotlin 1.4.21.
      • KotlinX Serialization 1.0.1.
      • kodein-Log 0.8.0.
      • Kodein-Memory 0.5.0.
    Source code(tar.gz)
    Source code(zip)
  • 0.4.1-beta(Nov 25, 2020)

  • 0.4.0-beta(Nov 2, 2020)

    • BREAKING CHANGES

      • JNI for desktop JVM artifacts renamed to kodein-db-jni-jvm, kodein-db-jni-jvm-linux, kodein-db-jni-jvm-macos & kodein-db-jni-jvm-windows (added -jvm-).
      • DB.factory renamed to DB.default. Not a breaking change if you are using DB.open & DB.destroy utilities.
    • MODULES

      • new kodein-leveldb-inmemory and kodein-db-inmemory modules that contain in-memory only backend. DO NOT USE IN PRODUCTION! This is for tests only!
    • CORE

      • Kotlin 1.4.10.
    • BUILD

      • Restored Windows build.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0-beta(Sep 27, 2020)

  • 0.2.0-beta(Sep 18, 2020)

Java embedded nosql document store

Nitrite Database NOsql Object (NO2 a.k.a Nitrite) database is an open source nosql embedded document store written in Java. It has MongoDB like API. I

Nitrite Database 713 Dec 23, 2022
A simple NoSQL client for Android. Meant as a document store using key/value pairs and some rudimentary querying. Useful for avoiding the hassle of SQL code.

SimpleNoSQL A simple NoSQL client for Android. If you ever wanted to just save some data but didn't really want to worry about where it was going to b

Colin Miller 389 Sep 25, 2022
An Android helper class to manage database creation and version management using an application's raw asset files

THIS PROJECT IS NO LONGER MAINTAINED Android SQLiteAssetHelper An Android helper class to manage database creation and version management using an app

Jeff Gilfelt 2.2k Jan 7, 2023
A library for reading Shared Preferences and Database values within the application.

AppDataReader A library for reading and writing Shared Preferences and Database values of the application within the device. Advantages of using this

Anshul Jain 124 Nov 25, 2022
A quick and easy database manager plugin library for your DBFlow databases.

DBFlowManager A quick and easy database manager and viewer plugin library for your DBFlow databases to view, insert, delete, update the tables directl

Wajahat Karim 26 Oct 21, 2022
A key-value database for Android

SnappyDB SnappyDB is a key-value database for Android it's an alternative for SQLite if you want to use a NoSQL approach. It allows you to store and g

Nabil Hachicha 1.8k Dec 28, 2022
Insanely easy way to work with Android Database.

Sugar ORM Insanely easy way to work with Android databases. Official documentation can be found here - Check some examples below. The example applicat

null 2.6k Dec 16, 2022
Android Database Performance Benchmarks

ℹ Check out our new performance test app that includes ObjectBox. Android Database Performance Benchmark This project evaluates Android databases and

Markus Junginger 80 Nov 25, 2022
Test any type of cloud database on Android apps. No need of a dedicated backend.

Test any type of cloud database on Android apps. No need of a dedicated backend.

Arjun 9 May 9, 2022
Android with Real-time Database

Android with Real-time Database It was too much effort to build my own real-time database, but the result really satisfying, so it was worth it. Note

null 4 Jun 14, 2022
Realm is a mobile database: a replacement for SQLite & ORMs

Realm is a mobile database that runs directly inside phones, tablets or wearables. This repository holds the source code for the Java version of Realm

Realm 11.4k Jan 9, 2023
ObjectBox is a superfast lightweight database for objects

ObjectBox Java (Kotlin, Android) ObjectBox is a superfast object-oriented database with strong relation support. ObjectBox is embedded into your Andro

ObjectBox 4.1k Dec 30, 2022
A helper library to help using Room with existing pre-populated database [].

Room now supports using a pre-packaged database out of the box, since version 2.2.0 https://developer.android.com/jetpack/androidx/releases/room#2.2.0

Ibrahim Eid 136 Nov 29, 2022
Android library for viewing and sharing in app databases.

DbInspector DbInspector provides a simple way to view the contents of the in-app database for debugging purposes. There is no need to pull the databas

Infinum 925 Dec 17, 2022
SQLDelight - Generates typesafe Kotlin APIs from SQL

SQLDelight See the project website for documentation and APIs SQLDelight generates typesafe kotlin APIs from your SQL statements. It verifies your sch

Cash App 4.9k Jan 5, 2023
A small library to help with Realm.IO integration in Android apps

Android Realm Asset Helper A small library of methods to help with Realm.IO integration in Android apps Copies a realm database from a the assets fold

Quality Mobile Puzzle Apps 29 Dec 28, 2021
A wrapper around Android's SQLiteDatabase with restoring capability

Restorable SQLiteDatabase RestorableSQLiteDatabase is a wrapper to replicate android's SQLiteDatabase class with restoring capability. This wrapper ma

Navid 21 Oct 21, 2022
an android library for debugging what we care about directly in app.

EN | 中文 Pandora is a tool box that allows you to inspect and modify what includes networks, databases, UIs, etc. directly in your application. It is s

linjiang 1.5k Dec 30, 2022
Core Data for Android

NexusData Core Data for Android NexusData is an object graph and persistence framework for Android. It allows for organizing and managing relational d

Dia Kharrat 71 Nov 11, 2022