DBless with Nucleoid runtime
Can Mingir
Posted on June 29, 2020
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
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.
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.
Hello World with Nucleoid. Nucleoid is a runtime environment that… | by Can Mingir | Nucleoid | Medium
Can Mingir ・ ・
Medium
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 ofDrivers
.
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
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
Posted on June 29, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.