Simple JSON database based on the file-access and server-client approach with the non-blocking server and the reactive (asynchronous non-blocking) client.
- Java 8
- Maven
First, clone or fork the repository:
$ git clone git@github.com:ttulka/thistledb.git
$ cd thistledb
Now build it and assemble:
$ mvn clean install -P localBuild
$ mvn package appassembler:assemble --file server-app/pom.xml
And finally run it:
$ cd server-app/target/server/bin
$ server
Type your command/query ending with ;
or stop the server and exit the console by typing quit
.
ThistleDB is based on the file-access. All the data are persistent on a disk.
Collections are separated data spaces with schema-less structures.
A collection contains a set of documents.
Collection name can contain only literals, digits and underscore _
.
Documents are JSON objects in a collection.
Elements are paths in a document.
Example (patient.name
is an element addressing a patient name in the document):
{
"patient" : {
"id" : "123456789",
"name" : "John Smith"
}
}
Name of an element can contain literals, digits, underscore _
and dash -
.
Example of valid element names:
name
123
patient-name_123
Values could be strings, numbers, boolean literals and null
.
All the commands and queries are SQL-like.
CREATE collection_name
DROP collection_name
ALTER collection_name ADD element [WHERE element op value [{AND|OR} element op value [...]]]
ALTER collection_name REMOVE element [WHERE element op value [{AND|OR} element op value [...]]]
INSERT INTO collection_name VALUES json_document[,json_document[...]]
SELECT {*|element[,element[...]]} FROM collection_name [WHERE element=value [{AND|OR} element=value [...]]]
DELETE FROM collection_name [WHERE element op value [{AND|OR} element op value [...]]]
UPDATE collection_name SET element=value[,element=value [...]] [WHERE element op value [{AND|OR} element op value [...]]]
Element is updated only when exists.
Operator | Meaning | Note |
---|---|---|
= |
Equal | |
!= |
Not equal | |
> |
Greater | |
>= |
Greater or equal | |
< |
Less | |
<= |
Less or equal | |
LIKE |
Equal by an expression | * any string, _ one character, ? any character (0,1) |
For accelerating the speed of searching can be used indexes on a collection.
Only simple-value elements (numbers, strings, ...) can be indexed.
Indexes are applied only on conditions with the equals operator =
.
As usual, indexes accelerate reading but degrading speed of data modifications - use them cleverly!
CREATE INDEX indexed_element ON collection_name
DROP INDEX indexed_element ON collection_name
DUAL collection is an immutable system "echo" collection which returns what it gets.
Query | Result |
---|---|
SELECT 123 FROM dual |
{ "value" : 123 } |
SELECT 1.23 FROM dual |
{ "value" : 1.23 } |
SELECT true FROM dual |
{ "value" : true } |
SELECT "abc" FROM dual |
{ "value" : "abc" } |
There are special element to be returned.
Query | Result | Example |
---|---|---|
SELECT * FROM dual |
empty | {} |
SELECT name FROM dual |
name of the collection | { "name" : "DUAL" } |
SELECT random FROM dual |
a random integer | { "random" : -980456651 } |
SELECT date FROM dual |
datetime in format yyyy-mm-dd H:m:s.ms |
{ "date" : "2017-02-19 14:25:02.122" } |
ThistleDB provides a Java driver to build a client from a Java application.
Client implements Reactive Streams, Version 1.0.0.
Client is not thread-safe, to ensure concurrency must be run within a synchronized context.
Copy the Maven dependency into your project:
<dependency>
<groupId>cz.net21.ttulka.thistledb</groupId>
<artifactId>thistledb-client</artifactId>
<version>1.0.0</version>
</dependency>
Open a client connection:
import cz.net21.ttulka.thistledb.client.Client;
// ...
Client client = new Client("localhost", 9658);
Create a collection:
client.executeCommand("CREATE test");
Put a document into the collection:
String json = "{\"patient\" : {\"id\" : \"123456789\", \"name\" : \"John Smith\"} }";
client.executeCommand("INSERT INTO test VALUES " + json);
Select the document from the collection (blocking):
String query = "SELECT * FROM test WHERE patient.id='123456789'";
List<String> result = client.executeQueryBlocking(query);
result.forEach(json -> System.out.println(json));
Select the document from the collection (non-blocking):
client.executeQuery(query).subscribe(System.out::println);
Close the client:
client.close();
Default server port is 9658.
Default data folder is data
, the path relative to the executing directory.
Maximum client connections the server accepts is 20.
Server can be started from the command-line or dynamically from a Java code.
After downloading binaries or compiling from the source code (see Get Started) run the server from the command-line:
$ cd server-app/target/server/bin
$ server
-p, --port <port>
-d, --dataDir <path>
-m, --maxConnections <maximum>
-c, --cacheExpirationTime <minutes>
Caching is active only together with indexes. Default value is 20 minutes, zero value means no caching.
Copy the Maven dependency into your project:
<dependency>
<groupId>cz.net21.ttulka.thistledb</groupId>
<artifactId>thistledb-server</artifactId>
<version>...</version>
</dependency>
For creating a new server object use ServerBuilder
:
Server.ServerBuilder builder = Server.builder();
Server server = builder.build();
Set the port:
int port = 1234;
Server server = Server.builder().port(port).build();
Set the data folder:
Path dataFolder = java.nio.file.Paths.get("/data");
Server server = Server.builder().dataFolder(dataFolder).build();
Set the cache expiration time (in minutes):
int cacheExpirationTime = 0; // zero means cache is disabled
Server server = Server.builder().cacheExpirationTime(cacheExpirationTime).build();
Setters can be mixed as wanted:
Server server = Server.builder().port(1234).cacheExpirationTime(5).build();
Maximum client connections can be changed by a setter:
int maxClientConnections = 10;
server.setMaxClientConnections(maxClientConnections);
server.start();
server.stop();
Console provides a remote access to the server from a command-line.
First, build it and assemble:
$ mvn clean install -P localBuild
$ mvn package appassembler:assemble --file console-app/pom.xml
And run it:
$ cd console-app/target/console/bin
$ console
Type your command/query ending with ;
or exit the console by typing quit
.