Nucleoid is an open source (Apache 2.0), a runtime environment that provides logical integrity in declarative programming, and at the same time, it stores declarative statements so that it doesn’t require external database, in short it can be used as database.
Hello World with Nucleoid
Can Mingir for Nucleoid ・ Jun 22 '20
Data Structure
Data structures are also defined in declarative syntax. Let's say name
is a variable, and by program requirements, name
must be:
- less than 10 characters
- first character is upper case
- contains no underscore character
so, this can be 3 separate declarations:
if( name.length > 10 ) {
throw "INVALID_SIZE"
}
if( ! /[A-Z]/.test( name.charAt(0) )) {
throw "INVALID_FIRST_CHARACTER"
}
if( name.indexOf("_") > -1 ) {
throw "INVALID_SPECIAL_CHARACTER"
}
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 three 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;
Both of first 2 options are not bidirectional.
Associative Entity
In this case, both objects will be registered in associative object:
> class User {}
> class Company {}
> class Registration {}
> if ( Registrations.filter( r => r.user == User ).length > 1 ) {
throw "USER_ALREADY_REGISTERED"
}
> user1 = new User();
> company1 = new Company();
> registration1 = new Registration();
> registration1.company = company1;
> registration1.user = user1;
Having a declaration of if ( Registrations.filter( r => r.user == User ).length > 1 ){ .. }
adds One-to-Many constraint. In this case, registering user1
to another company throws "USER_ALREADY_REGISTERED"
:
> company2 = new Company();
> registration2 = new Registration();
> registration2.company = company2
> registration2.user = user1;
> "USER_ALREADY_REGISTERED"
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 car 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
Reference: https://nucleoid.org/tutorial/
Top comments (0)