Maryk RocksDB Store
An embedded, high‑performance Maryk data store built on RocksDB.
Each DataModel is mapped to multiple column families (keys/table/index/unique and historic variants when enabled). See the detailed Architecture and Storage Layout. For migration runtime and operations, see Migrations.
Getting Started
Section titled “Getting Started”Use the following snippet:
RocksDBDataStore.open( keepAllVersions = false, keepUpdateHistoryIndex = false, relativePath = "path/to/folder/on/disk/for/store", dataModelsById = mapOf( 1u to Account, 2u to Course )).use { store -> // Run operations on the store
store.execute( Account.add( Account( username="test1", password="test1234" ), Account( username="test2", password="test1234" ) ) )}The .use { ... } scope closes the store automatically. If you don’t use use, call close() when finished to free native resources.
Need remote access to this local RocksDB store? Expose it with the
Remote Store via CLI serve.
Migrations and Version Updates
Section titled “Migrations and Version Updates”On open, the store compares stored model definitions with configured models and either applies compatible changes automatically or requires a migration for incompatible schema changes.
For the full migration model, hook contracts, runtime phases, control APIs, lease behavior, and operational guidance, see Migrations.
Group migration settings under migrationConfiguration = MigrationConfiguration(...).
Put migrationHandler, migrationExpandHandler, migrationVerifyHandler, and migrationContractHandler inside that configuration.
RocksDBDataStore.open( // True if the data store should keep all past versions of the data keepAllVersions = true, keepUpdateHistoryIndex = true, relativePath = "path/to/folder/on/disk/for/store", dataModelsById = mapOf( 1u to Account, 2u to Course ), migrationConfiguration = MigrationConfiguration( migrationHandler = { context -> val rocksDBDataStore = context.store val storedDataModel = context.storedDataModel val newDataModel = context.newDataModel // example when (newDataModel) { is Account -> when (storedDataModel.version.major) { 1.toUShort() -> { // Execute actions on rocksDBDataStore MigrationOutcome.Success } else -> MigrationOutcome.Fatal("Unsupported source version") } else -> MigrationOutcome.Fatal("Unsupported model") } } ), versionUpdateHandler = { rocksDBDataStore, storedDataModel, newDataModel -> // example when (storedDataModel) { null -> Unit // Do something when model did not exist before else -> Unit } })Lease Behavior
Section titled “Lease Behavior”RocksDB default lease is process-local (RocksDBLocalMigrationLease).
- Prevents duplicate migration runners inside one process.
- Cross-process migration lease is usually unnecessary for RocksDB because DB lock allows one opener.
- You can still inject custom
migrationLeasefor custom orchestration.
Platform Support
Section titled “Platform Support”This module is Kotlin Multiplatform and works on JVM, iOS, macOS, tvOS, watchOS, Android, Android Native, Windows and Linux via the rocksdb-multiplatform bindings.
For a deeper dive into how data is laid out and how queries execute, check the Architecture and Storage Layout docs.
Options
Section titled “Options”keepAllVersions: Keep historic table/index/unique column families for time-travel and change-history reads.keepUpdateHistoryIndex: Add anUpdateHistorycolumn family keyed by change version + key. With this enabled,scanUpdates(order = null)reads newest-first from this engine index by default.
Sensitive Properties
Section titled “Sensitive Properties”RocksDBDataStore.open accepts a fieldEncryptionProvider argument using the shared encryption contract
maryk.datastore.shared.encryption.FieldEncryptionProvider.
Use sensitive = true on property definitions to encrypt value payloads at rest.
val secret by string(index = 3u, sensitive = true)
val keyMaterial = AesGcmHmacSha256EncryptionProvider.generateKeyMaterial()val encryptionProvider = AesGcmHmacSha256EncryptionProvider( encryptionKey = keyMaterial.encryptionKey, tokenKey = keyMaterial.tokenKey)Notes:
- Sensitive values are encrypted in table payloads (latest + historic).
- Reads auto-decrypt based on an encrypted payload marker.
- Supported for simple value properties.
- Sensitive+
uniqueis supported whenfieldEncryptionProvideralso implementsmaryk.datastore.shared.encryption.SensitiveIndexTokenProvider. - Sensitive+indexed is not supported.
- Pass
fieldEncryptionProvider = encryptionProvidertoRocksDBDataStore.open(...).