SummaDB
This was a hierarchical database server similar to the original Firebase. Records were stored on a LevelDB on different paths, like:
/fruits/banana/color
:yellow
/fruits/banana/flavor
:sweet
And could be queried by path too, using HTTP, for example, a call to http://hostname:port/fruits/banana
, for example, would return a JSON document like
{
"color": "yellow",
"flavor": "sweet"
}
While a call to /fruits
would return
{
"banana": {
"color": "yellow",
"flavor": "sweet"
}
}
POST
, PUT
and PATCH
requests also worked.
In some cases the values would be under a special "_val"
property to disambiguate them from paths. (I may be missing some other details that I forgot.)
GraphQL was also supported as a query language, so a query like
query {
fruits {
banana {
color
}
}
}
would return {"fruits": {"banana": {"color": "yellow"}}}
.
SummulaDB
SummulaDB was a browser/JavaScript build of SummaDB. It ran on the same Go code compiled with GopherJS, and using PouchDB as the storage backend, if I remember correctly.
It had replication between browser and server built-in, and one could replicate just subtrees of the main tree, so you could have stuff like this in the server:
{
"users": {
"bob": {},
"alice": {}
}
}
And then only allow Bob to replicate /users/bob
and Alice to replicate /users/alice
. I am sure the require auth stuff was also built in.
There was also a PouchDB plugin to make this process smoother and data access more intuitive (it would hide the _val
stuff and allow properties to be accessed directly, today I wouldn’t waste time working on these hidden magic things).
The computed properties complexity
The next step, which I never managed to get fully working and caused me to give it up because of the complexity, was the ability to automatically and dynamically compute materialized properties based on data in the tree.
The idea was partly inspired on CouchDB computed views and how limited they were, I wanted a thing that would be super powerful, like, given
{
"matches": {
"1": {
"team1": "A",
"team2": "B",
"score": "2x1",
"date": "2020-01-02"
},
"1": {
"team1": "D",
"team2": "C",
"score": "3x2",
"date": "2020-01-07"
}
}
}
One should be able to add a computed property at /matches/standings
that computed the scores of all teams after all matches, for example.
I tried to complete this in multiple ways but they were all adding much more complexity I could handle. Maybe it would have worked better on a more flexible and powerful and functional language, or if I had more time and patience, or more people.
Screenshots
This is just one very simple unfinished admin frontend client view of the hierarchical dataset.
- https://github.com/fiatjaf/summadb
- https://github.com/fiatjaf/summuladb
- https://github.com/fiatjaf/pouch-summa