{"id":13564197,"url":"https://github.com/YgorCastor/ravix","last_synced_at":"2025-04-03T21:30:32.385Z","repository":{"id":37775544,"uuid":"444932841","full_name":"YgorCastor/ravix","owner":"YgorCastor","description":"Ravix is an Elixir Client for the amazing RavenDB","archived":false,"fork":false,"pushed_at":"2024-03-14T02:08:17.000Z","size":314,"stargazers_count":17,"open_issues_count":6,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-24T08:41:50.521Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/YgorCastor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":"ycastor.eth"}},"created_at":"2022-01-05T19:55:05.000Z","updated_at":"2024-11-07T16:49:12.000Z","dependencies_parsed_at":"2024-05-01T17:21:07.692Z","dependency_job_id":"51082cbf-ba7e-4b64-bd97-14fd9e9172aa","html_url":"https://github.com/YgorCastor/ravix","commit_stats":{"total_commits":139,"total_committers":5,"mean_commits":27.8,"dds":0.2517985611510791,"last_synced_commit":"52595cf9521d15201a0ff547d3411a6f36f16573"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YgorCastor%2Fravix","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YgorCastor%2Fravix/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YgorCastor%2Fravix/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/YgorCastor%2Fravix/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/YgorCastor","download_url":"https://codeload.github.com/YgorCastor/ravix/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247082838,"owners_count":20880727,"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":[],"created_at":"2024-08-01T13:01:27.849Z","updated_at":"2025-04-03T21:30:31.713Z","avatar_url":"https://github.com/YgorCastor.png","language":"Elixir","funding_links":["ycastor.eth"],"categories":["ORM and Datamapping","Languages"],"sub_categories":["Elixir"],"readme":"![ravix_logo](https://user-images.githubusercontent.com/1266053/148282743-79994640-4b15-4ffb-b477-5d0ed18072f9.png)\n\n[![Elixir CI](https://github.com/YgorCastor/ravix/actions/workflows/elixir.yml/badge.svg)](https://github.com/YgorCastor/ravix/actions/workflows/elixir.yml) [![Coverage Status](https://coveralls.io/repos/github/YgorCastor/ravix/badge.svg)](https://coveralls.io/github/YgorCastor/ravix)\n[![Hex](https://img.shields.io/hexpm/v/ravix?style=flat-square)](https://hex.pm/packages/ravix)\n\n\n# Ravix\n\nRavix is a in-development project to implement a client for the amazing [RavenDB NoSQL Database](https://ravendb.net/).\n\n# Usage\n\n## Installing\n\nAdd Ravix to your mix.exs dependencies\n\n```elixir\n{:ravix, \"~\u003e 0.10.0\"}\n```\n\n## Setting up your Repository\n\nCreate a Ravix Store Module for your repository\n\n```elixir\ndefmodule YourProject.YourStore do\n  use Ravix.Documents.Store, otp_app: :your_app\nend\n```\n\nYou can configure your Store in your config.exs files\n\n```elixir\nconfig :ravix, Ravix.Test.Store,\n  urls: [System.get_env(\"RAVENDB_URL\", \"http://localhost:8080\")],\n  database: \"test\",\n  retry_on_failure: true,\n  retry_backoff: 100,\n  retry_count: 3,\n  force_create_database: true,\n  document_conventions: %{\n    max_number_of_requests_per_session: 30,\n    max_ids_to_catch: 32,\n    timeout: 30,\n    use_optimistic_concurrency: false,\n    max_length_of_query_using_get_url: 1024 + 512,\n    identity_parts_separator: \"/\",\n    disable_topology_update: false\n  }\n```\n\nNote: All the calls to RavenDB are done via HTTP calls, to that we leverage the use of [Finch](https://github.com/sneako/finch), check there for adapter configurations.\n\nThen you can start the processes in your main supervisor\n\n```elixir\ndefmodule Ravix.TestApplication do\n  use Application\n\n  def start(_opts, _) do\n    children = [\n      {Finch, name: Ravix.Finch}, # By default the store searches for a Finch instance called 'Ravix.Finch' \n      {Ravix.Test.Store, [%{}]} # you can create multiple stores\n    ]\n\n    Supervisor.init(\n      children,\n      strategy: :one_for_one\n    )\n  end\nend\n```\n\n## Querying the Database\n\nAll operations supported by the driver should be executed inside a session, to open a session you can just call the `open_session/0` function from the store you defined. All the changes are only persisted when the function \n`Ravix.Documents.Session.save_changes/1` is called!\n\n```elixir\niex(2)\u003e Ravix.Test.Store.open_session()\n{:ok, \"985781c8-9154-494b-92d0-a66b49bb17ee\"}\n```\n\n### Inserting a new document\n\n```elixir\niex(2)\u003e Ravix.Test.Store.open_session()\niex(2)\u003e {:ok, session_id} = Ravix.Test.Store.open_session()\n{:ok, \"c4fb1f48-c969-4c76-9b12-5521926c7533\"}\niex(3)\u003e Ravix.Documents.Session.store(session_id, %{id: \"cat/1\", cat_name: \"Adolfus\"})\n{:ok, %{cat_name: \"Adolfus\", id: \"cat/1\"}}\niex(4)\u003e Ravix.Documents.Session.save_changes(session_id)\n{:ok,\n %{\n   \"Results\" =\u003e [\n     %{\n       \"@change-vector\" =\u003e \"A:264-vzsRp+yZT0GDkS5GJY/pAQ\",\n       \"@collection\" =\u003e \"@empty\",\n       \"@id\" =\u003e \"cat/1\",\n       \"@last-modified\" =\u003e \"2022-03-28T15:01:45.6545514Z\",\n       \"Type\" =\u003e \"PUT\"\n     }\n   ]\n }}\n```\n\n### Loading a document into the session\n\n```elixir\niex(3)\u003e {:ok, session_id} = Ravix.Test.Store.open_session()\n{:ok, \"d17e2be8-8c1e-4a59-8626-46725387f769\"}\niex(4)\u003e Ravix.Documents.Session.load(session_id, [\"cat/1\"])\n{:ok,\n %{\n   \"Includes\" =\u003e %{},\n   \"Results\" =\u003e [\n     %{\n       \"@metadata\" =\u003e %{\n         \"@change-vector\" =\u003e \"A:264-vzsRp+yZT0GDkS5GJY/pAQ\",\n         \"@id\" =\u003e \"cat/1\",\n         \"@last-modified\" =\u003e \"2022-03-28T15:01:45.6545514Z\"\n       },\n       \"cat_name\" =\u003e \"Adolfus\",\n       \"id\" =\u003e \"cat/1\"\n     }\n   ],\n   \"already_loaded_ids\" =\u003e []\n }}\n```\n\n### Querying using RQL\n\nRavenDB provides a query-language called [RQL](https://ravendb.net/docs/article-page/4.2/csharp/indexes/querying/what-is-rql), and for that Ravix provides two ways to deal with queries, using builder functions and raw RQLs\n\n#### RQL Builder\n\nYou can build RQLs using the builder provided by the `Ravix.RQL.Query` module\n\n```elixir\niex(11)\u003e from(\"@all_docs\") |\u003e where(equal_to(\"cat_name\", \"Adolfus\")) |\u003e list_all(session_id)\n{:ok,\n %{\n   \"DurationInMs\" =\u003e 1,\n   \"IncludedPaths\" =\u003e nil,\n   \"Includes\" =\u003e %{},\n   \"IndexName\" =\u003e \"Auto/AllDocs/Bycat_nameAndid\",\n   \"IndexTimestamp\" =\u003e \"2022-03-28T18:39:58.7637789\",\n   \"IsStale\" =\u003e false,\n   \"LastQueryTime\" =\u003e \"2022-03-28T18:49:05.9272430\",\n   \"LongTotalResults\" =\u003e 1,\n   \"NodeTag\" =\u003e \"A\",\n   \"ResultEtag\" =\u003e -4402181509807245325,\n   \"Results\" =\u003e [\n     %{\n       \"@metadata\" =\u003e %{\n         \"@change-vector\" =\u003e \"A:264-vzsRp+yZT0GDkS5GJY/pAQ\",\n         \"@id\" =\u003e \"cat/1\",\n         \"@index-score\" =\u003e 5.330733299255371,\n         \"@last-modified\" =\u003e \"2022-03-28T15:01:45.6545514Z\"\n       },\n       \"cat_name\" =\u003e \"Adolfus\",\n       \"id\" =\u003e \"cat/1\"\n     }\n   ],\n   \"SkippedResults\" =\u003e 0,\n   \"TotalResults\" =\u003e 1\n }}\n```\n\n#### Raw Query\n\n```elixir\niex(13)\u003e raw(\"from @all_docs where cat_name = \\\"Adolfus\\\"\") |\u003e list_all(session_id)\n{:ok,\n %{\n   \"DurationInMs\" =\u003e 1,\n   \"IncludedPaths\" =\u003e nil,\n   \"Includes\" =\u003e %{},\n   \"IndexName\" =\u003e \"Auto/AllDocs/Bycat_nameAndid\",\n   \"IndexTimestamp\" =\u003e \"2022-03-28T18:39:58.7637789\",\n   \"IsStale\" =\u003e false,\n   \"LastQueryTime\" =\u003e \"2022-03-28T18:53:27.4689173\",\n   \"LongTotalResults\" =\u003e 1,\n   \"NodeTag\" =\u003e \"A\",\n   \"ResultEtag\" =\u003e -4402181509807245325,\n   \"Results\" =\u003e [\n     %{\n       \"@metadata\" =\u003e %{\n         \"@change-vector\" =\u003e \"A:264-vzsRp+yZT0GDkS5GJY/pAQ\",\n         \"@id\" =\u003e \"cat/1\",\n         \"@index-score\" =\u003e 5.330733299255371,\n         \"@last-modified\" =\u003e \"2022-03-28T15:01:45.6545514Z\"\n       },\n       \"cat_name\" =\u003e \"Adolfus\",\n       \"id\" =\u003e \"cat/1\"\n     }\n   ],\n   \"SkippedResults\" =\u003e 0,\n   \"TotalResults\" =\u003e 1\n }}\n```\n\n### Collections\n\nRavenDB can organize the documents in collections, Ravix will automatically insert the document in a collection if you use the Ravix. Document macro. If you don't want to use the macro, your struct just need to have the `:@metadata` field.\n\n```elixir\ndefmodule Ravix.SampleModel.Cat do\n  use Ravix.Document, fields: [:id, :name, :breed]\nend\n```\n\n## Secure Server\n\nTo connect to a secure server, you can just inform the SSL certificates based on the [erlang ssl configs](https://www.erlang.org/doc/man/ssl.html) to Finch itself.\n\nE.g:\n\n```elixir\n{Finch, name: Ravix.Finch,\n    pools: %{\n      default: [\n        conn_opts: [\n          transport_opts: [\n            cert: DER_CERT,\n            key: DER_KEY\n          ]\n        ]\n      ]\n    }\n},\n```\n\n## Ecto\n\n \nWhat about querying your RavenDB using Ecto? [Ravix-Ecto](https://github.com/YgorCastor/ravix-ecto)\n\n## Current State\n\n* ~~Configuration Reading~~\n* ~~Session Management~~\n* ~~Request Executors~~\n* ~~Unsafe Server Connection~~\n* ~~Authenticated Server Connection~~\n* ~~Create Document~~\n* ~~Delete Document~~\n* ~~Load Document~~\n* ~~Queries Engine~~\n* ~~Clustering~~\n* ~~Topology Updates~~\n* Counters\n* Timeseries\n* Asynchronous Subscriptions\n* Attachments\n\nThe driver is working for the basic operations, clustering and resiliency are also implemented.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FYgorCastor%2Fravix","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FYgorCastor%2Fravix","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FYgorCastor%2Fravix/lists"}