{"id":37026415,"url":"https://github.com/kadekm/orientdb-scala-stream","last_synced_at":"2026-01-14T03:04:25.779Z","repository":{"id":34358548,"uuid":"38281018","full_name":"KadekM/orientdb-scala-stream","owner":"KadekM","description":"OrientDB scala reactive-streams (akka streams) library for non-blocking and live queries.","archived":false,"fork":false,"pushed_at":"2016-02-15T01:14:41.000Z","size":170,"stargazers_count":35,"open_issues_count":1,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-13T05:46:59.228Z","etag":null,"topics":["akka","orientdb","reactive-streams","scala"],"latest_commit_sha":null,"homepage":"","language":"Scala","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/KadekM.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":"2015-06-30T01:36:56.000Z","updated_at":"2022-11-06T07:36:06.000Z","dependencies_parsed_at":"2022-09-26T21:50:49.063Z","dependency_job_id":null,"html_url":"https://github.com/KadekM/orientdb-scala-stream","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/KadekM/orientdb-scala-stream","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KadekM%2Forientdb-scala-stream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KadekM%2Forientdb-scala-stream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KadekM%2Forientdb-scala-stream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KadekM%2Forientdb-scala-stream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KadekM","download_url":"https://codeload.github.com/KadekM/orientdb-scala-stream/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KadekM%2Forientdb-scala-stream/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408800,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["akka","orientdb","reactive-streams","scala"],"created_at":"2026-01-14T03:04:25.228Z","updated_at":"2026-01-14T03:04:25.766Z","avatar_url":"https://github.com/KadekM.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"_This library serves as Proof of Concept! It is not battle (production) tested._\n\n_If you are missing functionality, or something doesn't work, please either raise issue or make a PR. [See info](#info) at bottom._\n\n## OrientDB Scala Stream\n\nLibrary that allows you to execute `non blocking queries` and `live queries` on database, and treat results as reactive stream.\n\n__If your OrientDB version \u003c 2.2 you need to enable capabilities it in server config! Check OrientDB docs__\n```\n\u003chandler class=\"com.orientechnologies.orient.server.plugin.livequery.OLiveQueryPlugin\"\u003e\n\t\u003cparameters\u003e\n        \t\u003cparameter value=\"true\" name=\"enabled\"/\u003e\n        \u003c/parameters\u003e\n\u003c/handler\u003e\n```\n\nSupported\n\n- [Live queries](#live-queries) (experimental - [OrientDB documentation](http://orientdb.com/docs/last/Live-Query.html#whats-next))\n- [Nonblocking queries](#non-blocking-queries)\n- [Named query execution](#non-blocking-queries)\n- [Parametrized query execution](#non-blocking-queries)\n\nIf you're using SBT, add following to build.sbt:\n\n`libraryDependencies += \"com.marekkadek\" %% \"orientdb-scala-stream\" % \"0.5.4\"`\n\n## Live queries\n[(OrientDB documentation)](http://orientdb.com/docs/last/Live-Query.html)\n\nExample:\n```scala\nimport orientdb.streams._\n\nimplicit val db: ODatabaseDocumentTx = ???\nimplicit val loader = OrientLoaderDeserializing()\n\nval query = LiveQuery(bufferSize = 1000, OverflowStrategy.DropHead)\n                     (\"LIVE SELECT FROM Person\")\nSource.fromPublisher(query.execute())\n    .collect{ case Created(data) =\u003e data }\n    .takeWhile(_.field(\"name\").toString().contains(\"Pet\"))\n    .runForeach(println)\n```\nOnce you execute live query you get notifications for following events as they are streamed from OrientDB:\n- Loaded\n- Updated\n- Deleted\n- Created\n\nThe listener is automatically unsubscribed from OrientDB once the subscription is cancelled (executing command `live unsubscribe TOKEN_VALUE`)\n\nLive queries have internal buffer (which is being filled by DB, for example, when there is no demand downstreams, but events keep happening on DB) which you configure during creation of query. [Read here on overflow strategies and how to handle if you don't need/want any internal buffer](#overflow-strategies).\n\n## Non blocking queries\n[(OrientDB documentation)](http://orientdb.com/docs/last/Document-Database.html#non-blocking-query-since-v21)\n\nThere are two types of queries, both having some advantages and disadvantages:\n- Backpressuring (DB doesn't fetch more data than is demanded downstream)\n- Buffering (DB fetches data and fills buffer, even without demand, but sends it downstream accordingly)\n\nThey have same interface, so you can exchange one for another, depending on your need.\n\n```scala\nimport orientdb.streams._\n\nimplicit val db: ODatabaseDocumentTx = ???\nimplicit val loader = OrientLoaderDeserializing()\n\nval query = NonBlockingQueryBackpressuring[ODocument](\"SELECT * FROM Person\")\nval src = Source.fromPublisher(query.execute())\n          .runForeach(println)\n```\nThis will backpressure the databse - if there is no demand from downstream, database won't perform the fetch - thus non blocking queries have no need for internal buffer.Cancelling subscription will stop database from fetching next rows.\n\n```scala\nimport orientdb.streams._\n\nimplicit val db: ODatabaseDocumentTx = ???\nimplicit val loader = OrientLoaderDeserializing()\n\nval query = NonBlockingQueryBuffering[ODocument]\n        (bufferSize = 1000, OverflowStrategy.DropHead)\n        (\"SELECT * FROM Person WHERE name = :lookingFor\")\n        \nval src = Source.fromPublisher(query.executeNamed(\"lookingFor\" -\u003e \"Peter\"))\n          .map(myMethod)\n          .filter(myFilter)\n          .runFold(...) \n```\nThis will start the query on database, and results will be aggregated as database provides them. They will be pushed downstream accordingly to reactive-streams specification (based on demand...). Cancelling subscription will not stop DB from finishing query, but elements will no longer be buffered.\n\nBuffering queries have internal buffer which you configure during creation of query. [More here](#overflow-strategies).\n\n## Overflow strategies\nOverflow strategies are almost identical to akka-streams strategies. Overflow happens when buffer is full and you receive a message. Overflow strategy decides what will happen next. You can understand the buffer as FIFO collection. Here are illustrations of supported strategies (on left is the oldest element, thus element which is supposed to be emited on next demand). Suppose buffer size is 6:\n\n| Strategy   | Description              | Buffer visualisation                                |\n| :--------- |:------------------------ | :-------------------------------------------------- |\n| DropHead   | drops oldest in buffer   | `x ~\u003e [b u f f e r]` becomes `[u f f e r x]`        |\n| DropTail   | drops youngest in buffer | `x ~\u003e [b u f f e r]` becomes `[b u f f e x]`        |\n| DropBuffer | drops current buffer     | `x ~\u003e [b u f f e r]` becomes `[x]`                  | \n| DropNew    | drops incoming element   | `x ~\u003e [b u f f e r]` becomes `[b u f f e r]`        |\n| Fail       | emits error to stream    | `x ~\u003e [b u f f e r]` emits `BufferOverflowException`|\n\nYou may decide you don't want any internal buffer - for example in LiveQueries, when you are interested in changes that happen only AFTER there is active demand from downstream\n\n```scala\nval query = LiveQuery(bufferSize = 0, OverflowStrategy.DropNew)\n                     (\"LIVE SELECT FROM Person\")\n```\n\nSince it's curried you can easily define your own LiveQuery without buffer, such as `LiveQueryInstant`. Currently it is not provided as standard (as I tried to keep as few interfaces as possible).\n```scala\nval query = LiveQueryInstant(\"LIVE SELECT FROM Person\")\n```\n\n## Loader\n\nTo execute the queries you need following implicit (beside the regular ones):\n```scala\nimplicit val loader = OrientLoaderDeserializing()\n```\nLoader specified what to do with your entity before it is sent to the source of the stream (and thus possibly emitted downstreams). **It runs on thread which has database setup as ThreadLocal, so you can call methods which require it**. In stream operations, there is no such guarantee.\nYou can implement your `OrientLoader`.\n\n**The way this works may change in future.**\n\n## FAQ\nWhy does `Source.fromPublisher(query.execute()).runForeach(println)` produce inconstitent strings ? Sometimes with Person prefix, sometimes without ?\n* Depends on which thread gets to run the execution. It can actually be the thread that has database set in ThreadLocals, which then makes `ODocument.toString()` to fetch also schema. Please read _implicits loader part_.\n\n## Info\nThis library is yet in very early stage. There are lots of TODOs, and often you may discover better way to implement something - feel free to raise issue or submit PR, I will very much welcome it.\n\n### Current TODOs\n- finish some tests and move them from playground to real tests\n- clean up tests, better setup and teardown logic, remote/local traits\n- incode TODOs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkadekm%2Forientdb-scala-stream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkadekm%2Forientdb-scala-stream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkadekm%2Forientdb-scala-stream/lists"}