Packages

Low-level driver for ArangoDB

Current section

Files

Jump to
arango lib arangoex cursor.ex
Raw

lib/arangoex/cursor.ex

defmodule Arangoex.Cursor do
@moduledoc "ArangoDB Cursor methods"
alias Arangoex.Endpoint
defmodule Cursor do
@moduledoc false
@enforce_keys [:query]
defstruct [
:query,
:bind_vars,
:count,
:batch_size,
:cache,
:memory_limit,
:ttl,
:bind_vars,
:profile,
:optimizer_rules,
:satellite_sync_wait,
:full_count,
:max_plans,
]
@type t :: %__MODULE__{
# query: contains the query string to be executed
query: String.t,
# bind_vars: a map or keyword list containing the bounded variables
# with their respective values.
bind_vars: Keyword.t | Map.t,
# count: indicates whether the number of documents in the result
# set should be returned in the "count" attribute of the
# result. Calculating the "count" attribute might have a
# performance impact for some queries in the future so this
# option is turned off by default, and "count" is only returned
# when requested.
count: boolean,
# batchSize: maximum number of result documents to be
# transferred from the server to the client in one roundtrip. If
# this attribute is not set, a server-controlled default value
# will be used. A batchSize value of 0 is disallowed.
batch_size: pos_integer,
# cache: flag to determine whether the AQL query cache shall be
# used. If set to false, then any query cache lookup will be
# skipped for the query. If set to true, it will lead to the
# query cache being checked for the query if the query cache
# mode is either on or demand.
cache: boolean,
# memoryLimit: the maximum number of memory (measured in bytes)
# that the query is allowed to use. If set, then the query will
# fail with error "resource limit exceeded" in case it allocates
# too much memory. A value of 0 indicates that there is no
# memory limit.
memory_limit: non_neg_integer,
# ttl: The time-to-live for the cursor (in seconds). The cursor
# will be removed on the server automatically after the
# specified amount of time. This is useful to ensure garbage
# collection of cursors that are not fully fetched by
# clients. If not set, a server-defined value will be used.
# profile: If set to true, then the additional query profiling
# information will be returned in the sub-attribute profile of
# the extra return attribute if the query result is not served
# from the query cache.
# optimizer.rules (string): A list of to-be-included or
# to-be-excluded optimizer rules can be put into this attribute,
# telling the optimizer to include or exclude specific rules. To
# disable a rule, prefix its name with a -, to enable a rule,
# prefix it with a +. There is also a pseudo-rule all, which
# will match all optimizer rules.
optimizer_rules: [String.t],
# satelliteSyncWait: This enterprise parameter allows to
# configure how long a DBServer will have time to bring the
# satellite collections involved in the query into sync. The
# default value is 60.0 (seconds). When the max time has been
# reached the query will be stopped.
# fullCount: if set to true and the query contains a LIMIT
# clause, then the result will have an extra attribute with the
# sub-attributes stats and fullCount, { ... , "extra": {
# "stats": { "fullCount": 123 } } }. The fullCount attribute
# will contain the number of documents in the result before the
# last LIMIT in the query was applied. It can be used to count
# the number of documents that match certain filter criteria,
# but only return a subset of them, in one go. It is thus
# similar to MySQL's SQL_CALC_FOUND_ROWS hint. Note that setting
# the option will disable a few LIMIT optimizations and may lead
# to more documents being processed, and thus make queries run
# longer. Note that the fullCount attribute will only be present
# in the result if the query has a LIMIT clause and the LIMIT
# clause is actually used in the query.
full_count: boolean,
# maxPlans: Limits the maximum number of plans that are created
# by the AQL query optimizer.
max_plans: pos_integer,
}
end
# @doc """
# Create cursor
#
# POST /_api/cursor
# """
@spec cursor_create(Endpoint.t, Cursor.t) :: Arangoex.ok_error(map)
def cursor_create(endpoint, cursor) do
query = Map.get(cursor, :query)
bind_vars = Map.get(cursor, :bind_vars)
count = Map.get(cursor, :count)
batch_size = Map.get(cursor, :batch_size)
full_count = Map.get(cursor, :full_count)
max_plans = Map.get(cursor, :max_plans)
optimizer_rules = Map.get(cursor, :optimizer_rules)
top_level =
%{}
|> Map.merge(if query, do: %{"query" => query}, else: %{})
|> Map.merge(if bind_vars, do: %{"bindVars" => Enum.into(bind_vars, %{})}, else: %{})
|> Map.merge(if count, do: %{"count" => count}, else: %{})
|> Map.merge(if batch_size, do: %{"batchSize" => batch_size}, else: %{})
options =
%{}
|> Map.merge(if full_count, do: %{"fullCount" => full_count}, else: %{})
|> Map.merge(if max_plans, do: %{"maxPlans" => max_plans}, else: %{})
|> Map.merge(if optimizer_rules, do: %{"optimizer" => %{"rules" => optimizer_rules}}, else: %{})
cursor_request =
top_level
|> Map.merge(if Enum.any?(options), do: %{"options" => options}, else: %{})
endpoint
|> Endpoint.post("cursor", cursor_request)
end
# @doc """
# Delete cursor
# DELETE /_api/cursor/{cursor-identifier}
# """
@spec cursor_delete(Endpoint.t, Cursor.t) :: Arangoex.ok_error(map)
def cursor_delete(endpoint, cursor_id) do
endpoint
|> Endpoint.delete("cursor/#{cursor_id}")
end
# @doc """
# Read next batch from cursor
# PUT /_api/cursor/{cursor-identifier}
# """
@spec cursor_next(Endpoint.t, Cursor.t) :: Arangoex.ok_error(map)
def cursor_next(endpoint, cursor_id) do
endpoint
|> Endpoint.put("cursor/#{cursor_id}")
end
end