DBless with Nucleoid runtime

Can Mingir
Jun 29 · 4 min read
Image for post
Image for post

Well, you have to store somewhere.

Traditionally, a programming runtime processes functionalities, and as a result, it sends SQL statements to RDBMS. Even tough, there are alternative options arising in recent market such as NoSQL, Data Grid, in-memory database etc., they are still part of the same architecture of; programming runtime and persistence unit has to be separated.

Nucleoid is a declarative programming runtime with gathering both of processing and storing into the same runtime, so, it doesn’t require external database.

Nucleoid doesn’t require code files to compile, instead it receives ES6 (JavaScript) statements as declarative statements like databases receive SQL statements. Each > is an entry into the system.

> a = 1

First of, it runs the statement(s) in the state, which is the exact same as all JavaScript engines do, assigning a variable to value of 1.

Before closing the transaction, if the variable is part of other assignment, it runs dependents based on the graph, where all dependent information is held.

> a = 1
> b = a + 2
> c = b + 3
> a = 2
Image for post
Image for post

Since a is adjacent to b in the graph, the runtime reruns b = a + 2 , and updates b to 4 in the state along with a is being 2 in the state, and the same flow for c. If there is no logical conflict like circular dependency, it stores each statement as received on the disk as finalizing the transaction.

Image for post
Image for post

This algorithm parts from traditional way of storing and caching because databases usually cache data as it stores in the similar structure, but in this case, memory holds value of the variable, and disk stores statements as cumulative representation. This algorithm is also commonly used in event sourcing/CQRS, as event being received, the algorithm stores the event, and updates its result.

Performance

Since the state is already in memory, processing becomes faster because traditional programming runtime requires retrieving data regardless from database or cache server. Also, as mentioned, Nucleoid appends statements as received, and appending data on the file is the fastest disk operation. In addition, since there is no network communication required, it cuts that from the equation. For a trade off, it requires just-in-time compiling and computing on dependency graph as well as increases space complexity of storage on the hard drive.

Operations

Nucleoid supports all database operations in ES6 (JavaScript) syntax including relationships.

Relationships

Relationships of objects are defined similar to database’s relationships, but it requires to define in declarative syntax.

One-to-One

One-to-one’s defined as referring object’s property to another object instance.

> class Driver {}
> class Vehicle {}
> driver1 = new Driver();
> vehicle1 = new Vehicle();
> driver1.vehicle = vehicle1;

Bidirectional relationships requires additional declaration in order to keep both side synced, so not recommended unless absolutely required, associative entity may be used as alternative.

Still all the declarations are applicable to the property:

> Vehicle.type = "CAR"
> driver1.vehicle.type
"CAR"

One-to-Many

One-to-Many is defined in two ways:

List as in One’s side

It is a list created as property:

> class Customer {}
> class Order {}
> Customer.orders = [];> customer1 = new Customer();
> order1 = new Order();
> customer1.orders.push(order1);

Property as in Many’s side

It is a property created, which refers to other instance:

> class Employee {}
> class Project {}
> employee1 = new Employee()
> project1 = new Project();
> project1.employee = employee1;

Many-to-Many

Many-to-Many is relatively straightforward as only possible with associative entity without carrying any additional constraint.

> class Passenger {}
> class Flight {}
> class Ticket {}
> passenger1 = new Passenger();
> flight1 = new Flight();
> ticket1 = new Ticket();
> ticket1.passenger = passenger1
> ticket1.flight = flight1;
> flight2 = new Flight();> ticket2 = new Ticket();
> ticket2.passenger = passenger1
> ticket2.flight = flight2;

Queries

Queries is done with functional programming.

The runtime stores each instance into its class list like driver1 = new Driver() will be part of Drivers.

One-to-One

> Drivers.filter(d=>d.state== "GA").filter(d=>d.vehicle.year > 2010)
Finds drivers in GA state with card younger than 2010

One-to-Many

> Orders.filter( o => o.price > 100 && o.customer.id == 192)
Finds orders with bigger than $100 prize of customer with id 192

Other direction

> Customers.find(c=>c.id == 192).orders.filter(o=>o.price > 100)

Many-to-Many

> Tickets.filter(t => t.passenger.id == 6912 && t.flight.destination == "LA")
Finds ticket of passenger with id 6912 for destination to FL

These examples from nucleoid.org/tutorial

Image for post
Image for post

Nucleoid is open source (Apache 2.0), a runtime environment that allows declarative programming written in ES6 (JavaScript) syntax. Since statements are declarative, the runtime provides logical integrity and persistency as hiding technical details.

Join community at gitlab.com/nucleoid/nucleoid

Nucleoid

Declarative Runtime System

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store