• Stars
    star
    36
  • Rank 735,472 (Top 15 %)
  • Language
    Scala
  • License
    Other
  • Created over 2 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Lightning Memory Database (LMDB) for scala ZIO

Lightning Memory Database (LMDB) for ZIO

Why ZIO-lmdb ? Because I wanted a very simple embedded (in the same process) ACID database for small applications while keeping deployment, maintenance, upgrades as simple as possible.

ZIO-lmdb is based on the powerful lmdb-java library and bring a higher level API in order to enhance the developer experience.

So ZIO-lmdb is an embedded key/value database, with an easy to use opinionated API, choices have been made to make the developer experience as simple as possible :

  • JSON based storage using zio-json,
  • safe update by using a lambda which will be called with the previous value if it exists and returns the new value,
  • identifiers are managed by the developer, just use UUID or ULID.

API is designed to not lie, all functions signatures describe precisely what you must expect from them, thanks to ZIO and Scala3.

Definitions

For a better understanding, this library use a slightly different vocabulary from LMDB original one :

  • Database : (LMDB talk about Environment)
    • The place where the database file is stored on your file system
    • A set of configuration for this database (expected maximum size, expected collection number)
  • Collection : (LMDB talk about Database)
    • A sorted map where to store your data
    • One database contains multiple collection
  • Transaction : (the same for LMDB)
    • for global coherency within the same database
    • only one simultaneous write access is possible within the same database

Configuration

Configuration is based on the standard ZIO config mechanism, the default configuration provider uses environnment variables or java properties to resolve this library configuration parameters.

Configuration key Environment variable Description Default value
lmdb.name LMDB_NAME Database name, which will be also used as the directory name default
lmdb.home LMDB_HOME Where to store the database directory $HOME/.lmdb
lmdb.sync LMDB_SYNC Synchronize the file system with all database write operations false
lmdb.maxReaders LMDB_MAXREADERS The maximum number of readers 100
lmdb.maxCollections LMDB_MAXCOLLECTIONS The maximum number of collections which can be created 10_000
lmdb.mapSize LMDB_MAPSIZE The maximum size of the whole database including metadata 100_000_000_000L

Usages example

//> using scala  "3.3.0"
//> using dep "fr.janalyse::zio-lmdb:1.3.0"
//> using javaOpt "--add-opens", "java.base/java.nio=ALL-UNNAMED", "--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED"

import zio.*, zio.lmdb.*, zio.json.*
import java.io.File, java.util.UUID, java.time.OffsetDateTime

case class Record(uuid: UUID,name: String,age: Int,addedOn: OffsetDateTime) derives JsonCodec

object SimpleExample extends ZIOAppDefault {
  override def run = example.provide(LMDB.liveWithDatabaseName("lmdb-data-simple-example"), zio.Scope.default)

  val collectionName = "examples"
  val example        = for {
    _         <- LMDB.collectionCreate[Record](collectionName).ignore
    examples  <- LMDB.collectionGet[Record](collectionName)
    recordId  <- Random.nextUUID
    dateTime  <- Clock.currentDateTime
    record     = Record(recordId, "John Doe", 42, dateTime)
    _         <- examples.upsertOverwrite(recordId.toString, record)
    gotten    <- examples.fetch(recordId.toString).some
    collected <- examples.collect()
    _         <- Console.printLine(s"collection $collectionName contains ${collected.size} records")
    _         <- ZIO.foreach(collected)(record => Console.printLine(record))
    lmdb      <- ZIO.service[LMDB]
    _         <- Console.printLine("""LMDB standard tools can be used to manage the database content : sudo apt-get install lmdb-utils""")
    _         <- Console.printLine(s"""To get some statistics     : mdb_stat -s $collectionName ${lmdb.databasePath}/""")
    _         <- Console.printLine(s"""To dump collection content : mdb_dump -p -s $collectionName ${lmdb.databasePath}/""")
  } yield ()
}

SimpleExample.main(Array.empty)

To run the previous logic, you'll have to provide the LMDB layer, two layers are available :

  • LMDB.live : Fully configurable using standard zio-config
  • LMDB.liveWithDatabaseName("chosen-database-name") : to override/force the database name (quite useful when writing scala scripts)

ZIO-LMDB based Applications

Code snippets using ZIO-LMDB, runnable with scala-cli

Operating lmdb databases

LMDB standard tools can be used to manage the databases content : sudo apt-get install lmdb-utils

  • to get some database statistics : mdb_stat -a database_directory_path/
  • to dump the content of a database : mdb_dump -a -p database_directory_path/
  • to dump the content of a database collection : mdb_dump -s collectionName -p database_directory_path/
  • to restore some collection or the entire database use the command named mdb_load which uses the same format as for mdb_dump

As zio-lmdb is using json format, dumps are just text, which can be edited and then loaded back. So simple data migration is straightforward.

Requirements

When LVMDB is used as persistence store with recent JVM it requires some JVM options :

--add-opens java.base/java.nio=ALL-UNNAMED
--add-opens java.base/sun.nio.ch=ALL-UNNAMED

Contributors :)

More Repositories

1

jassh

High level scala SSH API for easy and fast operations on remote servers.
Scala
71
star
2

code-examples-manager

Software tool to manage your notes, scripts, code examples, configs,... to publish them as gists or snippets
Scala
37
star
3

jajmx

scala JMX API
Scala
31
star
4

sotohp

Photos management
Scala
27
star
5

scala-drools-dummy-project

Minimalist scala drools project
Scala
19
star
6

coursier-launcher

coursier docker container for efficient application or service download and startup
Makefile
9
star
7

zwords

A wordle game for communities
Scala
8
star
8

jaseries

scala API for time numerical series operations.
Scala
7
star
9

primes

Playing with primes using scala language. Draw Ulam spiral, ...
Scala
7
star
10

zio-worksheet

Simplified ZIO user experience in REPL, worksheet or script contexts
Scala
6
star
11

bootstrap

scala script bootstrap mechanism with #include support
Scala
6
star
12

the-weakest-link

Scala
4
star
13

custom-collection

Custom scala collection examples
Scala
4
star
14

scala-dummy-project

scala dummy project with standalone executable jar
Shell
3
star
15

drools-scripting

Drools made easy to use for scripting or testing purposes
Scala
2
star
16

codingame-with-scalakit-example

codingame scalakit example using git submodule to reference the scalakit
Scala
2
star
17

simple-plugin-architecture

Scala simple plugin architecture (with plugin automatic compilation if required)
Scala
2
star
18

exproxy

a 2005 personal project...
Java
2
star
19

cntlm

dockerized cntlm
Shell
2
star
20

primes-scalatra-app

Scala
1
star
21

naturalsort

scala naturalsort algorithm
Scala
1
star
22

web-echo

A websocket/webhook JSON data recorder with API
Scala
1
star
23

akka-sandbox

temporary project to test and learn AKKA 2
Scala
1
star
24

advent-of-code-2023

Scala
1
star
25

bullyboy

sha1 brute force attack
Scala
1
star
26

the-rules-for-good-code-examples

Several rules to write the best possible source code examples
1
star
27

data-recorder

Scala
1
star
28

advent-of-code-2020

Scala
1
star
29

jenkins-phantomjs-slave

jenkins slave with phantomjs 1.9 docker image
1
star
30

dock-primesui

Shell
1
star
31

jenkins

Jenkins docker image
Shell
1
star