zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

adapter.ex (5005B)


      1 defmodule Ecto.Adapter do
      2   @moduledoc """
      3   Specifies the minimal API required from adapters.
      4   """
      5 
      6   @type t :: module
      7 
      8   @typedoc """
      9   The metadata returned by the adapter `c:init/1`.
     10 
     11   It must be a map and Ecto itself will always inject
     12   two keys into the meta:
     13 
     14     * the `:cache` key, which as ETS table that can be used as a cache (if available)
     15     * the `:pid` key, which is the PID returned by the child spec returned in `c:init/1`
     16 
     17   """
     18   @type adapter_meta :: %{optional(:stacktrace) => boolean(), optional(any()) => any()}
     19 
     20   @doc """
     21   The callback invoked in case the adapter needs to inject code.
     22   """
     23   @macrocallback __before_compile__(env :: Macro.Env.t()) :: Macro.t()
     24 
     25   @doc """
     26   Ensure all applications necessary to run the adapter are started.
     27   """
     28   @callback ensure_all_started(config :: Keyword.t(), type :: :permanent | :transient | :temporary) ::
     29               {:ok, [atom]} | {:error, atom}
     30 
     31   @doc """
     32   Initializes the adapter supervision tree by returning the children and adapter metadata.
     33   """
     34   @callback init(config :: Keyword.t()) :: {:ok, :supervisor.child_spec(), adapter_meta}
     35 
     36   @doc """
     37   Checks out a connection for the duration of the given function.
     38 
     39   In case the adapter provides a pool, this guarantees all of the code
     40   inside the given `fun` runs against the same connection, which
     41   might improve performance by for instance allowing multiple related
     42   calls to the datastore to share cache information:
     43 
     44       Repo.checkout(fn ->
     45         for _ <- 100 do
     46           Repo.insert!(%Post{})
     47         end
     48       end)
     49 
     50   If the adapter does not provide a pool, just calling the passed function
     51   and returning its result are enough.
     52 
     53   If the adapter provides a pool, it is supposed to "check out" one of the
     54   pool connections for the duration of the function call. Which connection
     55   is checked out is not passed to the calling function, so it should be done
     56   using a stateful method like using the current process' dictionary, process
     57   tracking, or some kind of other lookup method. Make sure that this stored
     58   connection is then used in the other callbacks implementations, such as
     59   `Ecto.Adapter.Queryable` and `Ecto.Adapter.Schema`.
     60   """
     61   @callback checkout(adapter_meta, config :: Keyword.t(), (() -> result)) :: result when result: var
     62 
     63   @doc """
     64   Returns true if a connection has been checked out.
     65   """
     66   @callback checked_out?(adapter_meta) :: boolean
     67 
     68   @doc """
     69   Returns the loaders for a given type.
     70 
     71   It receives the primitive type and the Ecto type (which may be
     72   primitive as well). It returns a list of loaders with the given
     73   type usually at the end.
     74 
     75   This allows developers to properly translate values coming from
     76   the adapters into Ecto ones. For example, if the database does not
     77   support booleans but instead returns 0 and 1 for them, you could
     78   add:
     79 
     80       def loaders(:boolean, type), do: [&bool_decode/1, type]
     81       def loaders(_primitive, type), do: [type]
     82 
     83       defp bool_decode(0), do: {:ok, false}
     84       defp bool_decode(1), do: {:ok, true}
     85 
     86   All adapters are required to implement a clause for `:binary_id` types,
     87   since they are adapter specific. If your adapter does not provide binary
     88   ids, you may simply use `Ecto.UUID`:
     89 
     90       def loaders(:binary_id, type), do: [Ecto.UUID, type]
     91       def loaders(_primitive, type), do: [type]
     92 
     93   """
     94   @callback loaders(primitive_type :: Ecto.Type.primitive(), ecto_type :: Ecto.Type.t()) ::
     95               [(term -> {:ok, term} | :error) | Ecto.Type.t()]
     96 
     97   @doc """
     98   Returns the dumpers for a given type.
     99 
    100   It receives the primitive type and the Ecto type (which may be
    101   primitive as well). It returns a list of dumpers with the given
    102   type usually at the beginning.
    103 
    104   This allows developers to properly translate values coming from
    105   the Ecto into adapter ones. For example, if the database does not
    106   support booleans but instead returns 0 and 1 for them, you could
    107   add:
    108 
    109       def dumpers(:boolean, type), do: [type, &bool_encode/1]
    110       def dumpers(_primitive, type), do: [type]
    111 
    112       defp bool_encode(false), do: {:ok, 0}
    113       defp bool_encode(true), do: {:ok, 1}
    114 
    115   All adapters are required to implement a clause for :binary_id types,
    116   since they are adapter specific. If your adapter does not provide
    117   binary ids, you may simply use `Ecto.UUID`:
    118 
    119       def dumpers(:binary_id, type), do: [type, Ecto.UUID]
    120       def dumpers(_primitive, type), do: [type]
    121 
    122   """
    123   @callback dumpers(primitive_type :: Ecto.Type.primitive(), ecto_type :: Ecto.Type.t()) ::
    124               [(term -> {:ok, term} | :error) | Ecto.Type.t()]
    125 
    126   @doc """
    127   Returns the adapter metadata from its `c:init/1` callback.
    128 
    129   It expects a process name of a repository. The name is either
    130   an atom or a PID. For a given repository, you often want to
    131   call this function based on the repository dynamic repo:
    132 
    133       Ecto.Adapter.lookup_meta(repo.get_dynamic_repo())
    134 
    135   """
    136   def lookup_meta(repo_name_or_pid) do
    137     Ecto.Repo.Registry.lookup(repo_name_or_pid)
    138   end
    139 end