View Source Loupe.Ecto.Context (Loupe v0.9.0)

The context is the structure that goes through the query building process. It includes the user assigns which are passed down below in the ecto definition, but also includes a couple fields to make sure that query info are validated beforehand.

ecto-schema-validations

Ecto schema validations

Some things are validated before executing the query to avoid crashes during the query execution. These validations includs:

  • Validate that the fetched schema exists and a valid schema.
  • Validate that the queried field are valid on the attached schema and allowed.

It also extract the query bindings which are the queries associations and validates them. This is meant to allow someone to use posts.comments.user.name in a query and directly join the posts's comments and comments's user to filter its name.

binding-naming

Binding naming

Ecto requires named bindings to be atom (which makes total sense). To avoid generating atoms at runtimes in the system, any non-reserverd keyword is cast as string when generating the AST.

When building the Ecto query, the join statements uses bindings from a predefined set that you can find a the bottom of this file under the @binding_keys module attribute.

Link to this section Summary

Functions

Casts a sigil expression using the context's implementation

Initializes a query by scoping from the implementation

Instanciates a context with an implementation and some assigns. The assigns will be passed down to the implementation during to query building process to alter the definition dynamically.

Puts bindings in the context validation that bindings are either valid fields or associations.

Puts parameters compiling sigils and assigning variables

Puts root schema in the context validating it's a valid Ecto schema

Checks if a given schema field is allowed

Gets implementation schema fields

Gets implementation schemas

Same as selectable_fields/1 but for the root schema

Gets fields that can be selected infering the foreign keys. For instance, if someone allows user belong_to relationship on Post̀, the user_id is automatically returned and there is no need for it to be allowed.

Sorts binding in order to be join in order

Link to this section Types

@type assigns() :: assigns()
@type binding_path() :: [atom()]
@type bindings() :: %{required(binding_path()) => atom()}
@type implementation() :: module()
@type schema() :: Ecto.Queryable.t()
@type schemas() :: %{required(binary()) => schema()}
@type t() :: %Loupe.Ecto.Context{
  assigns: assigns(),
  bindings: bindings(),
  implementation: implementation(),
  parameters: map(),
  root_schema: schema(),
  variables: map()
}

Link to this section Functions

Link to this function

cast_sigil(context, arg)

View Source
@spec cast_sigil(t(), Loupe.Language.sigil_definition()) :: any()

Casts a sigil expression using the context's implementation

Link to this function

initialize_query(context)

View Source
@spec initialize_query(t()) :: Ecto.Query.t()

Initializes a query by scoping from the implementation

Link to this function

new(implementation, assigns, variables \\ %{})

View Source
@spec new(implementation(), assigns(), map()) :: t()

Instanciates a context with an implementation and some assigns. The assigns will be passed down to the implementation during to query building process to alter the definition dynamically.

Link to this function

put_bindings(context, bindings)

View Source
@spec put_bindings(t(), [[binary()]]) ::
  {:ok, t()} | {:error, {:invalid_binding, binary()}}

Puts bindings in the context validation that bindings are either valid fields or associations.

Link to this function

put_parameters(context, parameter_map)

View Source
@spec put_parameters(t(), map()) :: t()

Puts parameters compiling sigils and assigning variables

Link to this function

put_root_schema(context, schema)

View Source
@spec put_root_schema(t(), binary()) :: {:ok, t()} | {:error, :invalid_schema}

Puts root schema in the context validating it's a valid Ecto schema

Link to this function

schema_field_allowed?(context, schema, field)

View Source
@spec schema_field_allowed?(t(), schema(), atom()) :: boolean()

Checks if a given schema field is allowed

Link to this function

schema_fields(context, schema)

View Source
@spec schema_fields(t(), schema()) :: schema()

Gets implementation schema fields

@spec schemas(t()) :: schemas()

Gets implementation schemas

Link to this function

selectable_fields(context)

View Source
@spec selectable_fields(t()) :: [atom()]

Same as selectable_fields/1 but for the root schema

Link to this function

selectable_fields(context, schema)

View Source
@spec selectable_fields(t(), schema()) :: [atom()]

Gets fields that can be selected infering the foreign keys. For instance, if someone allows user belong_to relationship on Post̀, the user_id is automatically returned and there is no need for it to be allowed.

Link to this function

sorted_bindings(context)

View Source
@spec sorted_bindings(t()) :: [{binding_path(), atom()}]

Sorts binding in order to be join in order