{"id":16627114,"url":"https://github.com/ttulka/thistledb","last_synced_at":"2025-07-04T12:02:57.423Z","repository":{"id":57730150,"uuid":"93486518","full_name":"ttulka/thistledb","owner":"ttulka","description":"ThistleDB - Simple JSON Database","archived":false,"fork":false,"pushed_at":"2017-09-22T07:41:37.000Z","size":714,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-18T03:08:16.758Z","etag":null,"topics":["database","java","json","nosql","nosql-database","server-client"],"latest_commit_sha":null,"homepage":"http://thistledb.net21.cz","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ttulka.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-06T07:00:17.000Z","updated_at":"2018-01-17T09:30:11.000Z","dependencies_parsed_at":"2022-09-07T20:23:47.226Z","dependency_job_id":null,"html_url":"https://github.com/ttulka/thistledb","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ttulka%2Fthistledb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ttulka%2Fthistledb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ttulka%2Fthistledb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ttulka%2Fthistledb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ttulka","download_url":"https://codeload.github.com/ttulka/thistledb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243042892,"owners_count":20226719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","java","json","nosql","nosql-database","server-client"],"created_at":"2024-10-12T04:13:25.928Z","updated_at":"2025-03-11T13:32:22.818Z","avatar_url":"https://github.com/ttulka.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ThistleDB - Simple JSON Database\n\nSimple JSON database based on the **file-access** and **server-client** approach with the *non-blocking* server and the *reactive* (asynchronous non-blocking) client.\n\n## Prerequisites\n\n- Java 8\n- Maven \n\n## Get Started\n\nFirst, clone or fork the repository:\n```\n$ git clone git@github.com:ttulka/thistledb.git\n$ cd thistledb\n```\nNow build it and assemble:\n```\n$ mvn clean install -P localBuild\n$ mvn package appassembler:assemble --file server-app/pom.xml\n```\nAnd finally run it: \n```\n$ cd server-app/target/server/bin\n$ server\n```\nType your command/query ending with `;` or stop the server and exit the console by typing `quit`.\n\n### Data Structures\nThistleDB is based on the file-access. All the data are persistent on a disk.\n\n#### Collections\nCollections are separated data spaces with schema-less structures.\n\nA collection contains a set of documents.\n\nCollection name can contain only literals, digits and underscore `_`. \n\n#### Documents\nDocuments are JSON objects in a collection.\n\n##### Elements\nElements are paths in a document.\n\nExample (`patient.name` is an element addressing a patient name in the document):\n```json\n{\n    \"patient\" : {\n        \"id\" : \"123456789\",\n        \"name\" : \"John Smith\"\n    }\n}\n```\nName of an element can contain literals, digits, underscore `_` and dash `-`. \n\nExample of valid element names:\n```\nname\n123\npatient-name_123\n```\n##### Values\nValues could be strings, numbers, boolean literals and `null`.\n\n### Commands and Queries\nAll the commands and queries are SQL-like.\n\n#### Create a Collection\n```\nCREATE collection_name \n```\n#### Drop a Collection\n```\nDROP collection_name \n```\n#### Add an Element to Documents in a Collection\n```\nALTER collection_name ADD element [WHERE element op value [{AND|OR} element op value [...]]]  \n```\n#### Remove an Element from Documents in a Collection\n```\nALTER collection_name REMOVE element [WHERE element op value [{AND|OR} element op value [...]]]  \n```\n#### Insert a Document into a Collection\n```\nINSERT INTO collection_name VALUES json_document[,json_document[...]]\n```\n#### Select a Document from a Collection\n```\nSELECT {*|element[,element[...]]} FROM collection_name [WHERE element=value [{AND|OR} element=value [...]]]  \n```\n#### Delete a Document from a Collection\n```\nDELETE FROM collection_name [WHERE element op value [{AND|OR} element op value [...]]]  \n```\n#### Update a Document in a Collection\n```\nUPDATE collection_name SET element=value[,element=value [...]] [WHERE element op value [{AND|OR} element op value [...]]]  \n```\nElement is updated only when exists.\n\n### Operators\n| Operator   | Meaning                | Note                                                       | \n| ---------- | ---------------------- | ---------------------------------------------------------- |\n| `=`        | Equal                  |                                                            |\n| `!=`       | Not equal              |                                                            |\n| `\u003e`        | Greater                |                                                            |\n| `\u003e=`       | Greater or equal       |                                                            |\n| `\u003c`        | Less                   |                                                            |\n| `\u003c=`       | Less or equal          |                                                            |\n| `LIKE`     | Equal by an expression | `*` any string, `_` one character, `?` any character (0,1) |\n\n### Indexes \nFor accelerating the speed of searching can be used indexes on a collection.\n\nOnly simple-value elements (numbers, strings, ...) can be indexed.\nIndexes are applied only on conditions with the equals operator `=`.\n\nAs usual, indexes accelerate reading but degrading speed of data modifications - use them cleverly!  \n\n#### Create an Index for a Collection\n```\nCREATE INDEX indexed_element ON collection_name  \n```\n#### Drop an Index for a Collection\n```\nDROP INDEX indexed_element ON collection_name  \n```\n\n### DUAL Collection\nDUAL collection is an immutable system \"echo\" collection which returns what it gets.\n\n| Query                    | Result                |\n| ------------------------ | --------------------- |\n| `SELECT 123 FROM dual`   | `{ \"value\" : 123 }`   |\n| `SELECT 1.23 FROM dual`  | `{ \"value\" : 1.23 }`  |\n| `SELECT true FROM dual`  | `{ \"value\" : true }`  |\n| `SELECT \"abc\" FROM dual` | `{ \"value\" : \"abc\" }` |\n\nThere are special element to be returned.\n\n| Query                   | Result                                    | Example                                  |\n| ----------------------- | ----------------------------------------- | ---------------------------------------- |\n| `SELECT * FROM dual`      | *empty*                                 | `{}`                                     |\n| `SELECT name FROM dual`   | name of the collection                  | `{ \"name\" : \"DUAL\" }`                    |\n| `SELECT random FROM dual` | a random integer                        | `{ \"random\" : -980456651 }`              |\n| `SELECT date FROM dual`   | datetime in format `yyyy-mm-dd H:m:s.ms`| `{ \"date\" : \"2017-02-19 14:25:02.122\" }` |\n\n## Client\n\nThistleDB provides a *Java driver* to build a client from a Java application.\n\nClient implements [Reactive Streams, Version 1.0.0](http://www.reactive-streams.org).\n\nClient is not thread-safe, to ensure concurrency must be run within a synchronized context.\n\nCopy the Maven dependency into your project:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecz.net21.ttulka.thistledb\u003c/groupId\u003e\n    \u003cartifactId\u003ethistledb-client\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\nOpen a client connection:\n```\nimport cz.net21.ttulka.thistledb.client.Client;\n// ...\nClient client = new Client(\"localhost\", 9658);\n```\nCreate a collection:\n```\nclient.executeCommand(\"CREATE test\");\n```\nPut a document into the collection:\n```\nString json = \"{\\\"patient\\\" : {\\\"id\\\" : \\\"123456789\\\", \\\"name\\\" : \\\"John Smith\\\"} }\";\nclient.executeCommand(\"INSERT INTO test VALUES \" + json);\n```\nSelect the document from the collection (blocking):\n```\nString query = \"SELECT * FROM test WHERE patient.id='123456789'\";\nList\u003cString\u003e result = client.executeQueryBlocking(query);\n\nresult.forEach(json -\u003e System.out.println(json));\n```\nSelect the document from the collection (non-blocking):\n```\nclient.executeQuery(query).subscribe(System.out::println);\n```\nClose the client:\n```\nclient.close();\n```\n\n## Server\n\nDefault server port is **9658**. \n\nDefault data folder is `data`, the path relative to the executing directory.\n\nMaximum client connections the server accepts is **20**.\n\nServer can be started from the command-line or dynamically from a Java code.\n\n### Starting from a Command-Line\nAfter downloading binaries or compiling from the source code (see Get Started) run the server from the command-line:\n```\n$ cd server-app/target/server/bin\n$ server\n```\n\n#### Changing the Default Port\n```\n-p, --port \u003cport\u003e\n```\n#### Changing the Default Data Folder\n```\n-d, --dataDir \u003cpath\u003e\n```\n#### Maximum Client Connections\n```\n-m, --maxConnections \u003cmaximum\u003e\n```\n#### Caching \n```\n-c, --cacheExpirationTime \u003cminutes\u003e\n```\nCaching is active only together with indexes. Default value is 20 minutes, zero value means no caching.\n\n### Starting from a Java Code\nCopy the Maven dependency into your project:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecz.net21.ttulka.thistledb\u003c/groupId\u003e\n    \u003cartifactId\u003ethistledb-server\u003c/artifactId\u003e\n    \u003cversion\u003e...\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n#### Create a server instance\nFor creating a new server object use `ServerBuilder`:\n```\nServer.ServerBuilder builder = Server.builder();\nServer server = builder.build();\n```\nSet the port:\n```\nint port = 1234;\nServer server = Server.builder().port(port).build();\n```\nSet the data folder:\n```\nPath dataFolder = java.nio.file.Paths.get(\"/data\");\nServer server = Server.builder().dataFolder(dataFolder).build();\n```\nSet the cache expiration time (in minutes):\n```\nint cacheExpirationTime = 0;    // zero means cache is disabled\nServer server = Server.builder().cacheExpirationTime(cacheExpirationTime).build();\n```\nSetters can be mixed as wanted:\n```\nServer server = Server.builder().port(1234).cacheExpirationTime(5).build();\n```\nMaximum client connections can be changed by a setter:\n```\nint maxClientConnections = 10;\nserver.setMaxClientConnections(maxClientConnections);\n```\n#### Start and stop the server\n```\nserver.start();\nserver.stop();\n```\n\n## Console\n\nConsole provides a remote access to the server from a command-line.\n\nFirst, build it and assemble:\n```\n$ mvn clean install -P localBuild\n$ mvn package appassembler:assemble --file console-app/pom.xml\n```\nAnd run it: \n```\n$ cd console-app/target/console/bin\n$ console\n```\nType your command/query ending with `;` or exit the console by typing `quit`.\n\n## License\n\n[Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fttulka%2Fthistledb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fttulka%2Fthistledb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fttulka%2Fthistledb/lists"}