Popularity
3.3
Growing
Activity
5.0
-
15
4
4

Programming language: Elixir
License: Apache License 2.0

ravix alternatives and similar packages

Based on the "ORM and Datamapping" category.
Alternatively, view ravix alternatives based on common mentions on social networks and blogs.

Do you think we are missing an alternative of ravix or a related project?

Add another 'ORM and Datamapping' Package

README

ravix_logo

Elixir CI Coverage Status

Ravix

Ravix is a in-development project to implement a client for the amazing RavenDB NoSQL Database.

Usage

Instaling

Add Ravix to your mix.exs dependencies

{:ravix, "~> 0.1"}

Setting up your Repository

 

Create a Ravix Store Module for your repository

defmodule YourProject.YourStore do
  use Ravix.Documents.Store, otp_app: :your_app
end

 

You can configure your Store in your config.exs files

config :ravix, Ravix.TestStore,
  urls: [System.get_env("RAVENDB_URL", "http://localhost:8080")],
  database: "test",
  retry_on_failure: true,
  retry_backoff: 100,
  retry_count: 3,
  force_create_database: true,
  document_conventions: %{
    max_number_of_requests_per_session: 30,
    max_ids_to_catch: 32,
    timeout: 30,
    use_optimistic_concurrency: false,
    max_length_of_query_using_get_url: 1024 + 512,
    identity_parts_separator: "/",
    disable_topology_update: false
  }

 

Then you can start the processes in your main supervisor

defmodule Ravix.TestApplication do
  use Supervisor

  def init(_opts) do
    children = [
      {Ravix, [%{}]},
      {Ravix.TestStore, [%{}]} # you can create multiple stores
    ]

    Supervisor.init(
      children,
      strategy: :one_for_one
    )
  end

  def start_link(init_arg) do
    Supervisor.start_link(__MODULE__, init_arg, name: __MODULE__)
  end
end

 

Querying the Database

 

All 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 Ravix.Documents.Session.save_changes/1 is called!

iex(2)> Ravix.TestStore.open_session()
{:ok, "985781c8-9154-494b-92d0-a66b49bb17ee"}

Inserting a new document

iex(2)> Ravix.TestStore.open_session()
iex(2)> {:ok, session_id} = Ravix.TestStore.open_session()
{:ok, "c4fb1f48-c969-4c76-9b12-5521926c7533"}
iex(3)> Ravix.Documents.Session.store(session_id, %{id: "cat/1", cat_name: "Adolfus"})
{:ok, %{cat_name: "Adolfus", id: "cat/1"}}
iex(4)> Ravix.Documents.Session.save_changes(session_id)
{:ok,
 %{
   "Results" => [
     %{
       "@change-vector" => "A:264-vzsRp+yZT0GDkS5GJY/pAQ",
       "@collection" => "@empty",
       "@id" => "cat/1",
       "@last-modified" => "2022-03-28T15:01:45.6545514Z",
       "Type" => "PUT"
     }
   ]
 }}

Loading a document into the session

iex(3)> {:ok, session_id} = Ravix.TestStore.open_session()
{:ok, "d17e2be8-8c1e-4a59-8626-46725387f769"}
iex(4)> Ravix.Documents.Session.load(session_id, ["cat/1"])
{:ok,
 %{
   "Includes" => %{},
   "Results" => [
     %{
       "@metadata" => %{
         "@change-vector" => "A:264-vzsRp+yZT0GDkS5GJY/pAQ",
         "@id" => "cat/1",
         "@last-modified" => "2022-03-28T15:01:45.6545514Z"
       },
       "cat_name" => "Adolfus",
       "id" => "cat/1"
     }
   ],
   "already_loaded_ids" => []
 }}

Querying using RQL

RavenDB provides a query-language called RQL, and for that Ravix provides two ways to deal with queries, using builder functions and raw RQLs

RQL Builder

You can build RQLs using the builder provided by the Ravix.RQL.Query module

iex(11)> from("@all_docs") |> where(equal_to("cat_name", "Adolfus")) |> list_all(session_id)
{:ok,
 %{
   "DurationInMs" => 1,
   "IncludedPaths" => nil,
   "Includes" => %{},
   "IndexName" => "Auto/AllDocs/Bycat_nameAndid",
   "IndexTimestamp" => "2022-03-28T18:39:58.7637789",
   "IsStale" => false,
   "LastQueryTime" => "2022-03-28T18:49:05.9272430",
   "LongTotalResults" => 1,
   "NodeTag" => "A",
   "ResultEtag" => -4402181509807245325,
   "Results" => [
     %{
       "@metadata" => %{
         "@change-vector" => "A:264-vzsRp+yZT0GDkS5GJY/pAQ",
         "@id" => "cat/1",
         "@index-score" => 5.330733299255371,
         "@last-modified" => "2022-03-28T15:01:45.6545514Z"
       },
       "cat_name" => "Adolfus",
       "id" => "cat/1"
     }
   ],
   "SkippedResults" => 0,
   "TotalResults" => 1
 }}

Raw Query

iex(13)> raw("from @all_docs where cat_name = \"Adolfus\"") |> list_all(session_id)
{:ok,
 %{
   "DurationInMs" => 1,
   "IncludedPaths" => nil,
   "Includes" => %{},
   "IndexName" => "Auto/AllDocs/Bycat_nameAndid",
   "IndexTimestamp" => "2022-03-28T18:39:58.7637789",
   "IsStale" => false,
   "LastQueryTime" => "2022-03-28T18:53:27.4689173",
   "LongTotalResults" => 1,
   "NodeTag" => "A",
   "ResultEtag" => -4402181509807245325,
   "Results" => [
     %{
       "@metadata" => %{
         "@change-vector" => "A:264-vzsRp+yZT0GDkS5GJY/pAQ",
         "@id" => "cat/1",
         "@index-score" => 5.330733299255371,
         "@last-modified" => "2022-03-28T15:01:45.6545514Z"
       },
       "cat_name" => "Adolfus",
       "id" => "cat/1"
     }
   ],
   "SkippedResults" => 0,
   "TotalResults" => 1
 }}

Collections

RavenDB 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.

defmodule Ravix.SampleModel.Cat do
  use Ravix.Document, fields: [:id, :name, :breed]
end

Secure Server

To connect to a secure server, you can just inform the SSL certificate using the certificate or the certificate_file configuration.

config :ravix, Ravix.TestStore,
  urls: [System.get_env("RAVENDB_URL", "http://localhost:8080")],
  database: "test",
  certificate: CERT_IN_BASE_64,
  certificate_file: "/opt/certs/cert.pfx"

Current State

  • Configuration Reading
  • Session Management
  • Request Executors
  • Unsafe Server Connection
  • Authenticated Server Connection
  • Create Document
  • Delete Document
  • Load Document
  • Queries Engine (it works, but i'm not happy)
  • Clustering
  • Topology Updates
  • Counters
  • Timeseries
  • Asynchronous Subscriptions
  • Attachments

The driver is working for the basic operations, clustering and resiliency are also implemented.