Functions as Queries @ SwayDB
Tags: java, kotlin, scala, storage
Published: 2020-03-29 16:43:52


---
title: Functions as Queries @ SwayDB
published: true
description: Updating data in SwayDB using pure functions.
tags: java, kotlin, scala, storage
---

__Conditional updates & deletes__ are performed by submitting any **Java**,  **Scala**,  **Kotlin**  or any native  **JVM  code/function**. There is __no query language__. 

Being just JVM functions/code we can
- Be more __expressive__ in writing our query logic as we are not restricted by rules of a query language.
- Use __external Java libraries__ within our queries like Joda-Time for time management, Jackson or Circe for JSON parsing etc.
- Write __test-cases__ using familiar testing libraries like JUnit, kotlin.test, ScalaTest etc.
- __Type-safe__ - catch errors during compile time.  
- __Fast__ - No runtime parsing & compiling performance cost. See these [benchmarks](https://swaydb.simer.au/benchmarks/rocksdb/?language=scala/) that show __482,000+ writes per second__. Function updates follow the same write path as any basic write and do not incur any extra cost.

## Example

A simple example which creates a `Map<String, Double>` that stores __productName__ as key and __price__ as value. You can use custom classes (`Product.java` for values) here but for simplicity `String` and `Double` is used.

__Update logic__: If a product has less than 2 days left to expiration, give a generous 50% discount!

```java
//Our function that implements the update logic. 
//You can also use PureFunction.OnValue or PureFunction.OnKey.
PureFunction.OnKeyValue<String, Double, Return.Map<Double>> discount =  
  (String product, Double price, Optional<Deadline> deadline) -> {
    //if there are less than 2 days to expiry then apply discount.  
    if (deadline.isPresent() && deadline.get().timeLeft().minusDays(2).isNegative()) {  
      double discountedPrice = price * 0.50; //50% discount.
      if (discountedPrice <= 10) { //If the price is below $10
        //return Return.expire(Duration.ZERO); //expire it
        return Return.remove(); //or remove the product
      } else {  
        return Return.update(discountedPrice); //else update with the discounted price
      }  
    } else {
      return Return.nothing(); //else do nothing.
    }
  };  

//create our map with functions enabled.    
Map<String, Double, PureFunction<String, Double, Return.Map<Double>>> products =  
  MapConfig.functionsOn(stringSerializer(), doubleSerializer())  
    .registerFunction(discount) //register the discount function
    .get();  

//insert two products that expire after a day. 
products.put("MacBook Pro", 2799.00, Duration.ofDays(1));  
products.put("Tesla", 69275.0, Duration.ofDays(1));  

//apply the discount function.
products.applyFunction("MacBook Pro", "Tesla", discount);  
```

We can print the content of the Map with the following

```java
products.stream().forEach(System.out::println);    
```

Before the discount is applied will print
> KeyVal(MacBook Pro, 2799.0)
> KeyVal(Tesla, 69275.0)
> 

After the discount is applied prints
> KeyVal(MacBook Pro, 1399.5)
> KeyVal(Tesla, 34637.5)

See the above example on GitHub - [DiscountApp.java](https://github.com/simerplaha/SwayDB.java.examples/blob/master/src/main/java/functions/DiscountApp.java).

## What is function ID?

Each `PureFunction` type also implement a `String id` value which gets stored in the database. Currently the `id` is defaulted to `this.getClass().getName();` which can be overridden by your function.  

## Note & TODOs
- The function itself is not serialised. Only the function's `id` gets serialised and stored in the database. TODO - Serialisable functions.
- `.mightContainFunction` can be used to check if a function is in use. TODO - Automatic function removal.
- TODO - stronger types when `registering` and `applying` function.

## Useful links

-   [SwayDB](https://github.com/simerplaha/SwayDB)  on GitHub.
-   [Java](https://github.com/simerplaha/SwayDB.java.examples)  examples repo.
-   [Kotlin](https://github.com/simerplaha/SwayDB.kotlin.examples)  examples repo.
-   [Scala](https://github.com/simerplaha/SwayDB.scala.examples)  examples repo.
-   [Documentation](https://swaydb.simer.au/).