MultiMap – Tables in SwayDB

Posted on

MultiMap is an extension of Map data type which allows storing multiple Maps within a single SwayDB instance. It mimics SQL’s Table which can be used to seggregate data.

MultiMap is just a thin layer that uses custom types and KeyOrdering to manage data segregation.

The following code snippets demo few core functionality of MultiMap like nesting, expiration, streaming, transactions, replace & remove.



Initialise MultiMap

import swaydb._ //import SwayDB's API
import swaydb.serializers.Default._ //import default serialisers

//initialise an in-memory multiMap  
val map = memory.MultiMap_EAP[String, Long, String, Nothing, Bag.Less]()

//or initialise an persistent multiMap 
val pMap = persistent.MultiMap_EAP[String, Long, String, Nothing, Bag.Less]("myDir")
Enter fullscreen mode

Exit fullscreen mode

  • String – The type of Map ID. In SQL this would be Table Name.
  • Long – The type of Key for key-values stored in this Map. In SQL this would be primary key.
  • String – The type of Value for key-values stored in the Map. In SQL this would be the Table row.
  • Nothing – The function type. Using Nothing disables functions. Instead of a query language, SwayDB allows complex data modifications by submitting pure JVM functions. In SQL these would be CREATE, INSERT & UPDATE queries. You can read more about this here.
  • Bag.Less – The effect type for all API calls. We can use Cats, Monix, ZIO, Try, Future or any other custom effect type. Using Bag.Less disables effect management and simply returns the result as output.



Creating Tables

The following creates two tables under the root map.

val usersTable = map.schema.init(mapKey = "Users Table")  
val productsTable = map.schema.init(mapKey = "Products Table")

//this create another child table under Users Table.
val userTablesChild = usersTable.schema.init(mapKey = "Users Table's child")

//read all tables keys of userTable
val keys: Stream[String] = usersTable.schema.keys
//read all child tables of userTable
val tables = usersTable.schema.stream
Enter fullscreen mode

Exit fullscreen mode



Schema tree

Alt Text



Creating tables with default expiration

Similar to above we can also create Tables/Maps that expire.

import scala.concurrent.duration._  

map.schema.init(mapKey = "Users Table", expireAfter = 10.days)  
map.schema.init(mapKey = "Products Table", expireAt = 10.seconds.fromNow)
Enter fullscreen mode

Exit fullscreen mode



Removing and replacing tables

Replace creates a new table clearing all existing data including all existing child tables.

//replace
map.schema.replace(mapKey = "Users Table", expireAfter = 10.days)

//or remove to delete the map/table
map.schema.remove(mapKey = "Users Table")
Enter fullscreen mode

Exit fullscreen mode



Transactions

Modifications to multiple Tables can be performed as a single batch transaction. The following snippet creates and commits two transaction entries for two different tables.

//prepare statement for userTable and productTable  
val transaction =  
  usersTable.toTransaction(Prepare.Put(key = 1L, value = "user1")) ++  
    productsTable.toTransaction(Prepare.Put(key = 1L, value = "product1"))  

//commit to root map  
map.commit(transaction)  

usersTable.get(1L) shouldBe Some("user1")  
productsTable.get(1L) shouldBe Some("product1")
Enter fullscreen mode

Exit fullscreen mode

See transaction for a list of all Prepare statements.



Code

See MultiMap_Example.scala on Github which uses custom types with circe for serialisation.

Please consider staring the SwayDB project if you find it useful.



EAP

MultiMap is currently in preview version (EAP). See performance improvement task #235.



GitHub repos

Check out related GitHub repos

Leave a Reply

Your email address will not be published.